CSS 预处理器

Sass (Syntactically Awesome StyleSheets),是由Ruby语言编写的一款css预处理语言,诞生于2007年,有着严格的缩进风格。官方样式库为 Compass

Scss (Sassy CSS),一款css预处理语言,SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。SCSS 需要使用分号和花括号而不是换行和缩进。SCSS 对空白符号不敏感。兼容CSS。

Less 是由 Alexis Sellier于2009年编写的一个CSS 预处理器,最开始由 Ruby 书写,后来改为 JavaScript。Less 由 Sass 启发,语法更接近于CSS,完全兼容CSS。

Stylus 是由 TJ Holowaychuk 编写的一款CSS预处理器,诞生于2010年。官方样式库为 nib

这些CSS预处理器都支持一些常用的CSS语法扩展,比如
变量 (variables)、嵌套 (nested rules)、混合 (mixins)、继承(extends)、导入 (imports)、函数(functions)
但在语法和功能性上有些许差异。

特点

Scss 优点:功能更强大,文档丰富,缺点:在国内使用较少,安装不太方便
Less 优点:语法简单,国内使用量较多 缺点:功能支持上不丰富
Stylus 优点:功能强大,语法简洁,框架较新,社区活跃,缺点:与原生css语法差异较大

基本语法

Less & Scss:

1
2
3
.box {
display: block;
}

Sass & Stylus:

1
2
.box
display: block

嵌套语法 nested rule

三者的嵌套语法都是一致的,引用父级选择器的标记均为 & 以 less 为例。

1
2
3
4
5
.a {
&.b {
color: red;
}
}

Scss支持属性嵌套:

1
2
3
4
5
6
7
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}

变量 variable

Less:使用 @ 声明变量

1
2
3
4
5
@red: #c00;

strong {
color: @red;
}

Scss:使用 $ 声明变量

1
2
3
4
5
$red: #c00;

strong {
color: $red;
}

Stylus:使用 = 声明变量

1
2
3
4
red = #c00

strong
color: red

@ 该字符在css中是一种已经被多次使用的规则(例如 @media @keyframes @supports),以后也可能被扩展,变量名用 @ 开头很可能会和以后的新 @ 规则冲突。

Scss 和 Stylus 提供了仅当变量不存在时才赋值的功能:

Scss:

1
2
3
4
5
$x: 1;
$x: 5 !default;
$y: 3 !default;

// $x = 1, $y = 3

Stylus:

1
2
3
4
5
x = 1
x := 5 // or x ?= 5
y = 3

// x = 1, y = 3

混入 mixin

混入(mixin)提供了样式层面的抽象。

混入有两种方式:

  1. 直接在目标位置混入另一个类样式(输出已经确定,无法使用参数);
  2. 定义一个不输出的样式片段(可以输入参数),在目标位置输出。

Less支持无参和带参的混入,也支持对已有类样式的混入:

1
2
3
4
5
6
7
8
9
10
11
12
13
.alert {
font-weight: 700;
}

.highlight(@color: red) {
font-size: 1.2em;
color: @color;
}

.heads-up {
.alert;
.highlight(red);
}

Scss 用 @mixin@include 两个指令表明了混入的声明和引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}

.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}

Stylus 和 Sass 类似,但不用什么特殊的标记来引入:

1
2
3
4
5
6
7
border-radius(n)
-webkit-border-radius: n
-moz-border-radius: n
border-radius: n

.circle
border-radius(50%)

Stylus 支持像原生css语法一样使用 mixin 的功能:

1
2
.circle
border-radius: 50%

继承 extend

如果多个地方都混入同样的代码,会造成输出代码的多次重复。

Less 使用类似伪类的方式 :extend() 来实现继承:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.message {
padding: 10px;
border: 1px solid #eee;
}

.warning {
&:extend(.message);
color: #e2e21e;
}
/* Or:
.warning:extend(.message) {
color: #e2e21e;
}
*/

同时,Less 默认只继承父类本身的样式,如果要同时继承嵌套定义在父类作用域下的样式,得使用关键字 all,例如 &:extend(.message all);

Stylus 和 Scss 使用 @extend 来实现继承:

1
2
3
4
5
6
7
8
9
.message {
padding: 10px
border: 1px solid #eee
}

.warning {
@extend .message
color: #e2e21e
}

占位 placeholder

Scss 和 Stylus 支持占位操作符,Scss 的占位符为 % ,Stylus 的占位符为 $,占位只存在于预处理器的编译过程中(类似 mixin),但不同之处是它可以被继承。

Scss 中的占位如下:

1
2
3
4
5
6
7
8
9
%red-card {
border: 1px solid #300;
background-color: #ecc;
color: #c00;
}

.alert {
@extend %red-card;
}

Stylus 中的占位如下:

1
2
3
4
5
6
7
$red-card
border: 1px solid #300
background-color: #ecc
color: #c00

.alert
@extend $red-card

导入 import

三种预处理器均支持 @import 导入样式文件,Stylus 还支持 @require 对同一个文件只导入一次

函数 functions

三种预处理器都自带了很多内置函数,三者调用函数的方式几乎一致,不同之处在于 Sass 和 Stylus 支持直接指定参数名的方式传入参数。Scss 和 Stylus 都支持添加自定义函数,Scss 中自定义函数需要用到 @function @return 关键字,在 Stylus 中,这些都是隐含的,最后一个表达式的值会作为返回值

Stylus:

1
2
3
4
subtract(a, b)
a - b

subtract(b: 10, a: 25) // same as substract(25, 10)

Scss:

1
2
3
4
5
6
7
8
$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width($n: 5); }

逻辑控制 control directives/conditionals

Scss 中通过常见的 @if、@else if、@else 实现条件分支,通过 @for、@each、@while 实现循环,配合 map 和 list 这两种数据类型可以轻松地实现多数编程语言提供的功能。

在 Stylus 中,不需要使用 @ 规则,提供了 if、else if、else、unless、for…in 来实现类似功能,语法比 Sass 更简洁灵活。

Less没有提供逻辑控制功能,可以通过 mixin 来模拟。

tips

使用 scss 需要安装 node-sass 这个npm包,在不设置镜像的情况下安装十分缓慢,容易失败。