Sass速通(一):变量与运算

2021-09-26 11:35:23 浏览数 (1)

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'.
除法运算

在 , -, *, /, % 几种运算符中, / 比较特殊,它不仅可以用作除法,还可以用作分隔符。 以下几种情况, / 将被认为是除法运算符:

  • 表达式中包含变量或函数返回值
  • 表达式被圆括号包裹
  • 表达式为复合表达式的一部分
代码语言:javascript复制
$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

0 人点赞