Sass 是一种 CSS 的预编译语言,预编译指在使用前需要先把它编译为 CSS,然后再交给浏览器执行。 Sass 中的变量提供了数据复用的方式,声明的变量可以用于选择器、属性和属性值等各种地方。一旦变量发生变化,所有应用的地方都将发生变化。
变量
在 Sass 中标识一个变量需要使用 $ 符号,如
代码语言:javascript复制$color: white;
如果要使用多个单词命名,最好使用中横线或下划线连接的方式,这两种命名方式虽然不同,如 danger-color 和 danger_color,但是却指向同一个变量。
代码语言:javascript复制$danger-color: red;
.danger {
color: $danger_color;
}
$warn-color: yellow;
$warn_color: orange;
.warn {
// $warn_color: orange;
color: $warn-color;
}
编译后
代码语言:javascript复制.danger {
color: red;
}
.warn {
color: orange;
}
插值
我们可以使用插值语法将变量插入到某个位置,无论插入位置是作为选择器、属性,还是属性值。
代码语言:javascript复制$selector: h1;
$prop: color;
$value: grey;
#{$selector} {
#{$prop}: #{$value};
}
编译后
代码语言:javascript复制h1 {
color: grey;
}
类型
变量支持以下几种类型:
- 数字,如 10、10px
- 字符串,包括有引号和无引号两种,如 "width"、Arial
- 颜色,如 white、#FFF、rgba(255, 255, 255, 0)
- 布尔,true 和 false
- 空值,null
- 数组(List),如 1.5em 1em 0 2em, Helvetica, Arial, sans-serif
- Map,相当于 JavaScript 的 object,如 (key1: vlaue1, key2: value2)
文档上表示 Sass 有六种数据类型,实际上是把 List 和 Map 当成了一种(值列表)。
数组(List)
数组元素使用空格或逗号分隔,数组中可以包含子数组,可以使用和父级不同的分隔方式或使用圆括号来表示子数组,如
代码语言:javascript复制$list1: 1px 2px, 3px 4px;
或
代码语言:javascript复制$list2: (1px 2px) (3px 4px);
在 Sass 中,这两种方式都定义了一个包含子数组的数组,但在编译后的 CSS 却不一样。
代码语言:javascript复制$list1: 1px 2px, 3px 4px;
$list2: (1px 2px) (3px 4px);
.inner {
margin: $list1;
padding: $list2;
}
编译后
代码语言:javascript复制.inner {
margin: 1px 2px, 3px 4px;
padding: 1px 2px 3px 4px;
}
这是由于 CSS 不支持圆括号的写法,因此 list2 会被拆开为一组值;而 CSS 支持逗号作分隔,所以 list1 会被编译为两组值。
Map
Map 提供了键值对的表示方式,与List不同的是,它必须被圆括号包裹,键值对之间使用逗号分隔。
代码语言:javascript复制$map: (width: 1px, color: red, style: solid);
Map 可用于 List 可用的任何地方,键值对会被自动转化为数组形式,如 (key1: value1, key2: value2) 会被转化为 (key1 value1) (key2 value2)。
默认值
在 Sass 中,可以使用 !default 为变量设置默认值,如
代码语言:javascript复制$color: white !default;
如果变量没有被重新赋值,那么就使用默认值,否则使用新定义的值,无论新值是在上文还是下文中定义的。
代码语言:javascript复制$color: red;
$color: blue !default;
.inner {
color: $color;
}
编译后
代码语言:javascript复制.inner {
color: red;
}
如果上面没有定义 $color: red; 那么 color 将取默认值 blue。
运算
在 Sass 中,我们可以使用 == 或 != 来对所有数据类型判断是否相等。此外,不同的数据类型也有各自不同的运算方式。
数字运算
由于数字具有不同类型,所以在计算的时候会进行类型转换。
代码语言:javascript复制.inner {
width: 1in 10px;
height: 10px 1in;
margin: 10px 1;
}
编译后
代码语言:javascript复制.inner {
width: 1.1041666667in;
height: 106px;
margin: 11px;
}
特殊类型之间不能进行运算(没有明确的换算关系),比如 px 和 %、px 和 vw 等,在编译时会报错:
代码语言:javascript复制Incompatible units: 'px' and '%'.
代码语言:javascript复制Incompatible units: 'px' and 'vw'.
除法运算
在 , -, *, /, % 几种运算符中, / 比较特殊,它不仅可以用作除法,还可以用作分隔符。 以下几种情况, / 将被认为是除法运算符:
- 表达式中包含变量或函数返回值
- 表达式被圆括号包裹
- 表达式为复合表达式的一部分
$width: 1000px;
p {
// 纯CSS,不作除法
font: 10px / 8px;
// 使用变量,除法
width: $width / 2;
// 使用函数返回值,除法
width: round(1.5) / 2;
// 使用圆括号,除法
height: (500px / 2);
// 作为表达式的一部分,除法
margin-left: 5px 8px / 2px;
}
编译后
代码语言:javascript复制p {
font: 10px / 8px;
width: 500px;
width: 1;
height: 250px;
margin-left: 9px;
}
如果你想用 / 分隔两个变量,而不是让它们作除法,你应该使用插值语法,如
代码语言:javascript复制font: #{$font-size}/#{$line-height}
字符串运算
拼接字符串
可以使用 来拼接字符串。
代码语言:javascript复制$str1: Myriad;
$str2: ' Pro';
p::after {
// 有引号字符串在前,输出有引号字符串
content: $str2 $str1;
// 无引号字符串在前,输出无引号字符串
font-family: $str1 $str2;
}
编译后
代码语言:javascript复制p::after {
content: " ProMyriad";
font-family: Myriad Pro;
}
字符串插值
可以使用插值语法在字符串中插入数据。如果插入的值为 null,会被替换为空串。
代码语言:javascript复制$value1: 'world';
$value2: null;
p::after {
content: 'Hello #{$value1}! Hello #{$value2}!';
}
编译后
代码语言:javascript复制p::after {
content: "Hello world! Hello !";
}
颜色运算
三色道
如果只有三色道的颜色参与计算,在计算时,会将红绿蓝三色道拆开分开计算,然后再组合在一起。
代码语言:javascript复制.inner {
color: #010101 #020202;
border-color: rgb(3, 3, 3) - #010101;
background-color: rgb(1, 1, 1) * 3;
outline-color: (#030303 / 3);
}
编译后
代码语言:javascript复制.inner {
color: #030303;
border-color: #020202;
background-color: #030303;
outline-color: #010101;
}
透明色道
如果使用透明色道 alpha channel(rgba & hsla),那么只有当 alpha 值相同时才能进行运算。
代码语言:javascript复制p {
color: rgba(255, 0, 0, 0.75) rgba(0, 255, 0, 0.75);
}
编译后
代码语言:javascript复制p {
color: rgba(255, 255, 0, 0.75);
}
如果想修改颜色的 alpha 值,可以使用 opacify() 或 transparentize() 这两个方法。
代码语言:javascript复制$translucent-red: rgba(255, 0, 0, 0.5);
p {
color: opacify($translucent-red, 0.3); // 0.3
background-color: transparentize($translucent-red, 0.25); // 变0.25
}
编译后
代码语言:javascript复制p {
color: rgba(255, 0, 0, 0.8);
background-color: rgba(255, 0, 0, 0.25);
}
布尔运算
Sass 中的布尔运算可以使用 and 和 or。
代码语言:javascript复制$bool1: 2 > 1 or 0 > 1; // true
$bool2: 2 > 1 and 3 > 1; // true
$bool3: 2 > 1 and 0 > 1; // false
p::after {
content: '#{$bool1} #{$bool2} #{$bool3}'
}
编译后
代码语言:javascript复制p::after {
content: "true true false";
}
数组(List)
操作数组需要使用 SassScript 提供的一些方法。
append
append(list, value, [separator]) 用于在列表尾部添加新的元素; separator 为可选参数,默认自动监测,可选值有 comma、space、auto,用于设置元素间的分隔符。
代码语言:javascript复制> $list: 1px 2px;
> append($list, 3px);
> # 1px 2px 3px
> append($list, 3px, comma);
> # 1px, 2px, 3px
index
index(list, value) 用于获取目标值在数组中所处的下标,下标从 1 开始。
代码语言:javascript复制> $list: 1px 2px;
> index($list, 1px);
> # 1
nth
nth(list, index) 用于获取指定下标对应的值。
代码语言:javascript复制> $list: 1px 2px;
> nth($list, 1);
> # 1px
set-nth
set-nth(list, index, value) 用于设置指定下标对应的值。
代码语言:javascript复制> $list: 1px 2px;
> set-nth($list, 1, 5px);
> # 5px 2px
length
length(list) 用于获取列表长度。
代码语言:javascript复制> $list: 1px 2px 3px 4px;
> length($list);
> # 4
join
join(list1, list2, [separator], [bracketed]) 用于合并两个数组; separator 为可选参数,默认自动监测,可选值有 comma、space、auto,用于设置元素间的分隔符; bracketed 为可选参数,可选值有 true 和 false,用于设置输出的数组是否被方括号 [] 包裹。
代码语言:javascript复制> $list1: 1px, 2px; # 逗号分隔
> $list2: 3px 4px; # 空格分隔
> join($list1, $list2);
> # 1px, 2px, 3px, 4px
> join($list2, $list1);
> # 1px 2px 3px 4px
> join($list1, $list2, 'space');
> # 1px 2px 3px 4px
> join($list1, $list2, 'space', true);
> # [1px 2px 3px 4px]
zip
zip(list1, list2...) 可将多个数组按下标相同为一组,重新组成一个新的多维数组。
代码语言:javascript复制> $width-map: 1px 2px 3px;
> $color-map: red green blue;
> $style-map: solid dashed dotted;
> zip($width-map, $color-map, $style-map)
> # 1px red solid, 2px green dashed, 3px blue dotted
Map
Map 可用 List 的所有方法,在使用时,Map 会被转化为 List。除此之外,Map 还拥有其它一些方法。
map-get
map-get(map, key) 用于获取指定键对应的值。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-get($map, width);
> # 1px
> map-get($map, color);
> # red
map-merge
map-merge(map1, map2) 用于添加新的键值对(合并 Map)。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-merge($map, (radius: 5px));
> # (width: 1px, color: red, style: solid, radius: 5px)
map-remove
map-remove(map, key1, key2...) 用于移除指定的键值对,参数可写多个键。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-remove($map, width, color);
> # (style: solid)
map-has-key
map-has-key(map, key) 用于判断 Map 中是否含有某个键值对。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-has-key($map, width);
> # true
> map-has-key($map, radius);
> # false
map-keys
map-keys(map) 用于获取 Map 中所有的键。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-keys($map)
> # width, color, style
map-values
map-values(map) 用于获取 Map 中所有的键值。
代码语言:javascript复制> $map: (width: 1px, color: red, style: solid);
> map-values($map)
> # 1px, red, solid