介绍
stylus跟sass和less一样都是css预处理框架,2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,官网的介绍为:富于表现力、动态的、健壮的 CSS
因为stylus出现的比较晚,因此它的语法比较新。
Stylus默认使用 .styl 的作为文件扩展名,支持多样性的CSS语法。
安装
$ npm install stylus --save-dev
$ npm install stylus-loader --save-dev
使用
Stylus 特性
注释
stylus支持三种注释:
单行注释 //
多行注释 /**/
以及多行缓冲注释/*!*/
单行注释在编译之后会被删除,多行注释会被保留,多行缓冲注释相当于告诉Stylus压缩的时候这段无视直接输出。
选择器
html
body
margin 0
padding 0
编译之后的css
html,
body {
margin: 0;
padding: 0;
}
在stylus中,认为对于元素样式的设置 , {} : ; 是无意义的,因此在stylus中可以不用书写它们。同样因为没有来这些符号,所有空白符,换行,空格以及tab都很重要,写的时候要慎重。
变量
stylus是用js写的,因此很多语法跟js很像,比如js定义变量:
var color = 'red';
stylus中定义变量:
color = red
//或者添加标识符 $
$color = red
属性查找
Stylus有另外一个很酷的独特功能,不需要分配值给变量就可以定义引用属性。如下:
#logo
position absolute
top 50%
left 50%
width 150px
height 80px
margin-left -(@width / 2)
margin-top -(@height / 2)
这样就可以简单的通过前置@字符在属性名前来访问该属性名对应的值。
另外使用案例是基于其他属性有条件地定义属性。在下面这个例子中,我们默认指定z-index值为1,但是,只有在z-index之前未指定的时候才这样:
position(arg)
position arg
z-index 1 unless @z-index
#logo
z-index 20
position absolute
#logo2
position absolute
属性会“向上冒泡”查找堆栈直到被发现,或者返回null(如果属性搞不定)。下面这个例子,@color最后是blue.
body
color red
ul
li
color blue
a
background-color @color
插值
Stylus支持通过使用{}字符包围表达式来插入值,其会变成标识符的一部分。例如,-webkit-{'border' + '-radius'}等同于-webkit-border-radius 比如:
vendor(prop, args)
-webkit-{prop} args
-moz-{prop} args
{prop} args
border-radius(arg)
vendor('border-radius', arg)
button
border-radius 1px 2px 3px 4px
编译之后
button {
-webkit-border-radius: 1px 2px 3px 4px;
-moz-border-radius: 1px 2px 3px 4px;
border-radius: 1px 2px 3px 4px;
}
选择器插值
table
for row in 1 2 3 4 5
tr:nth-child({row})
height: 10px * row
编译过后:
table tr:nth-child(1) {
height: 10px;
}
table tr:nth-child(2) {
height: 20px;
}
table tr:nth-child(3) {
height: 30px;
}
table tr:nth-child(4) {
height: 40px;
}
table tr:nth-child(5) {
height: 50px;
}
混合
stylus中支持混合,语法跟js中定义函数很像,它的作用是用来复制样式或者兼容浏览器
js中定义函数:
function 函数名称 ( ) { }
在stylus中定义混合语法:
混合名称()
//定义内容
使用混合的三种方式:
1.混合名称() ,参数集合中可以传递参数,多个参数使用逗号隔开
2.混合名称 参数 ,多个参数使用逗号隔开
3.混合名称 参数 ,多个参数使用空格隔开
混合分类
1.属性混合
封装一个属性,用来兼容各个浏览器
特点:通常以属性名称定义混合,来覆盖原有的属性,兼容浏览器
2.样式混合
封装的是多个属性,用来复用样式
//属性混合
border-radius(n)
-webkit-border-radius n
-moz-border-radius n
-o-border-radius n
-ms-border-radius n
border-radius n
box-shadow(bs1, bs2)
-webkit-box-shadow bs1, bs2
-moz-box-shadow bs1, bs2
-o-box-shadow bs1, bs2
-ms-box-shadow bs1, bs2
box-shadow bs1, bs2
form input[type=button]
border-radius 5px
box-shadow 2px 4px red, 10px 20px green
//样式混合
size(w = 300px, h = 200px, color = red)
width w
height h
background color
div
/*第一种*/
size(500px, 200px , blue)
/*第二种*/
size 500px, 200px, blue
/*第三种*/
size 500px 200px blue
编译之后
form input[type=button] {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-o-border-radius: 5px;
-ms-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 2px 4px red 10px 20px green;
-moz-box-shadow: 2px 4px red 10px 20px green;
-o-box-shadow: 2px 4px red 10px 20px green;
-ms-box-shadow: 2px 4px red 10px 20px green;
box-shadow: 2px 4px red 10px 20px green;
}
div {
width: 500px;
height: 200px;
background: blue;
}
注意:
1.混合的参数集合绝对不能省略
2.混合名称与参数集合之间绝对不能有空格
3.如果参数中出现了空格,我们要使用第二种方式
方法
函数
Stylus强大之处就在于其内置的语言函数定义。其定义与混入(mixins)一致;却可以返回值。
返回值
很简单的例子,两数值相加的方法:
add(a, b)
a + b
body
padding add(10px, 5)
编译之后
body {
padding: 15px;
}
默认参数
add(a, b = a)
a + b
add(10, 5)
// => 15
add(10)
// => 20
导入 @import
sylus还可以引入外部的stylus文件
动画
stylus会根据@keyframes自动创建兼容浏览器的样式,但是内容样式如果出现了css3则不会处理,需要使用混合书写的方式进行处理
举个栗子:
div
width 100px
height 100px
background red
animation move 5s
//定义transform混合
transform(arg...)
-webkit-transform arg
-moz--transform arg
-o--transform arg
-ms--transform arg
transform arg
//定义move动画
@keyframes move
from
margin-left 0
transform rotate(0)
to
margin-left 100%
transform rotate(360deg)
编译之后:
div {
width: 100px;
height: 100px;
background: red;
animation: move 5s;
}
@-webkit-keyframes move {
from {
margin-left: 0;
-webkit-transform: rotate(0);
-moz--transform: rotate(0);
-o--transform: rotate(0);
-ms--transform: rotate(0);
transform: rotate(0);
}
to {
margin-left: 0;
-webkit-transform: rotate(360deg);
-moz--transform: rotate(360deg);
-o--transform: rotate(360deg);
-ms--transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes move {
from {
margin-left: 0;
-webkit-transform: rotate(0);
-moz--transform: rotate(0);
-o--transform: rotate(0);
-ms--transform: rotate(0);
transform: rotate(0);
}
to {
margin-left: 0;
-webkit-transform: rotate(360deg);
-moz--transform: rotate(360deg);
-o--transform: rotate(360deg);
-ms--transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes move {
from {
margin-left: 0;
-webkit-transform: rotate(0);
-moz--transform: rotate(0);
-o--transform: rotate(0);
-ms--transform: rotate(0);
transform: rotate(0);
}
to {
margin-left: 0;
-webkit-transform: rotate(360deg);
-moz--transform: rotate(360deg);
-o--transform: rotate(360deg);
-ms--transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-ms-keyframes move {
from {
margin-left: 0;
-webkit-transform: rotate(0);
-moz--transform: rotate(0);
-o--transform: rotate(0);
-ms--transform: rotate(0);
transform: rotate(0);
}
to {
margin-left: 0;
-webkit-transform: rotate(360deg);
-moz--transform: rotate(360deg);
-o--transform: rotate(360deg);
-ms--transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes move {
from {
margin-left: 0;
-webkit-transform: rotate(0);
-moz--transform: rotate(0);
-o--transform: rotate(0);
-ms--transform: rotate(0);
transform: rotate(0);
}
to {
margin-left: 0;
-webkit-transform: rotate(360deg);
-moz--transform: rotate(360deg);
-o--transform: rotate(360deg);
-ms--transform: rotate(360deg);
transform: rotate(360deg);
}
}
继承 @extend
.message
padding 10px
border 1px solid #eee
.warning
@extend .message
color #E2E21E
编译之后:
.message,
.warning {
padding: 10px;
border: 1px solid #eee;
}
.warning {
color: #E2E21E;
}
@extend嵌套选择器
form
input[type=text]
padding 5px
border 1px solid #eee
color #ddd
textarea
@extends form input[type=text]
padding 10px
编译之后:
form input[type=text],
form textarea {
padding: 5px;
border: 1px solid #eee;
color: #ddd;
}
textarea {
padding: 10px;
}
CSS字面量
不管什么原因,如果遇到Stylus搞不定的特殊需求,你可以使用@css使其作为CSS字面量解决
@css {
.ie-opacity {
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=25);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=25)";
}
}
编译为:
.ie-opacity {
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=25);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=25)";
}
字符转义
Stylus可以字符转码。这可以让字符变成标识符,或是渲染成字面量。注意Stylus中/当作为属性使用的时候需要用括号括起来:
body
font 14px/1.4
font (14px/1.4)
编译为:
body {
font: 14px/1.4;
font: 10px;
}
问题:在vue cli 3.X如何使用全局的stylus,不需要每个组件里面再引入一次?
需要在vue.config.js中配置
// vue.config.js
const path = require('path')
module.exports = {
chainWebpack: config => {
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('stylus').oneOf(type)))
},
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/styles/imports.styl'),
],
})
}
然后在main.js中引入公共样式文件,这样就不需要在组件里面再引入一次公共样式啦
官网:http://stylus-lang.com/
参考中文文档:https://www.zhangxinxu.com/jq/stylus/