本篇介绍sass的数据类型, 函数functions, 和操作符operators, 任何一个语言都有基本的数据类型,操作符,方法或者函数,sass给css带来的新特性里
自然少不了它们.
本篇主要介绍Sass里的数据类型和操作符,基本的数据类型有数字,字符串,colors,列表,字典,boolean,null和函数引用
1. 数据类型
Sass里的基本数据类型有如下
1.1. Numbers数值
像素,英尺,浮点数等等都算是数字类型,css支持的单位sass都支持
1
2
3
4
5
6
7
|
@debug 100; // 100
@debug 0.8; // 0.8
@debug 16px; // 16px
@debug 5px * 2px; // 10px*px (read "square pixels")
@debug 5.2e3; // 5200
@debug 6e-2; // 0.06
|
1.1.1. 不同的单位
同单位和不同单位可以相乘和相除, 分子是原来被除数的单位,分母是除数的单位
1
2
3
4
5
6
7
8
9
|
@debug 4px * 6px; // 24px*px (read "square pixels")
@debug math.div(5px, 2s); // 2.5px/s (read "pixels per second")
// 3.125px*deg/s*em (read "pixel-degrees per second-em")
@debug 5px * math.div(math.div(30deg, 2s), 24em);
$degrees-per-second: math.div(20deg, 1s);
@debug $degrees-per-second; // 20deg/s
@debug math.div(1, $degrees-per-second); // 0.05s/deg
|
不同领域的单位不能相加减
1
2
3
4
5
6
|
// CSS defines one inch as 96 pixels.
@debug 1in + 6px; // 102px or 1.0625in
@debug 1in + 1s;
// ^^^^^^^^
// Error: Incompatible units s and in.
|
像下面这样用速度(每像素所需事件) x 距离,可以得到总时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$transition-speed: math.div(1s, 50px);
@mixin move($left-start, $left-stop) {
position: absolute;
left: $left-start;
transition: left ($left-stop - $left-start) * $transition-speed;
&:hover {
left: $left-stop;
}
}
.slider {
@include move(10px, 120px);
}
|
输出
1
2
3
4
5
6
7
8
9
10
11
|
.slider {
position: absolute;
left: 10px;
transition: left 2.2s;
}
.slider:hover {
left: 120px;
}
|
1.1.2. 注意事项
在创建数字变量的时候,尽量直接带上单位,不要出现差值这样的定义方式,比如#{$number}px
,这会被解释成一个字符串,
应该直接定义成$num1 = 20px
或者 $num1 = $num2 * 1px
sass里50%
和0.5
一个是百分比,一个是数值,两者完全不同.
math.div($percentage, 100%)
可以返回小数, 相反的$decimal * 100%
会得到一个百分比数.
1.1.3. 精度
sass支持小数点后面10位, 所以使用的时候注意:
- sass只会取前10位, 编译后也只会保留小数点后10位
- 比较操作符会比较也是基于小数点后10位
- 一个数字和整数的差距比
0.0000000001
小, 当做需要整数参数的函数实参的时候,就被认为是整数, 比如3.00000000009
1.2. String字符串
在sass里带引号的和不带引号的一些字面量, 比如颜色名称, 粗细等等都算字符串
Sass: sass:string (sass-lang.com)里提供了一些常用的字符串工具函数,比如下面的加引号和去引号
1
2
3
4
|
@use "sass:string";
@debug string.unquote(".widget:hover"); // .widget:hover
@debug string.quote(bold); // "bold"
|
1.2.1. Escape转义
和大部分语言一样.\
可以用来转义特殊字符串, 引号,unicode字符串(16进制),换行符, .
等等
1
2
3
4
5
|
@debug "\""; // '"'
@debug \.widget; // \.widget
@debug "\a"; // "\a" (a string containing only a newline)
@debug "line1\a line2"; // "line1\a line2"
@debug "Nat + Liz \1F46D"; // "Nat + Liz 👭"
|
1.2.2. Quoted带引号的
\a
代表新行,换行
- 单双引号前面加
\
\
可以用\\
表示
1
2
3
4
5
6
7
|
@debug "Helvetica Neue"; // "Helvetica Neue"
@debug "C:\\Program Files"; // "C:\\Program Files"
@debug "\"Don't Fear the Reaper\""; // "\"Don't Fear the Reaper\""
@debug "line1\a line2"; // "line1\a line2"
$roboto-variant: "Mono";
@debug "Roboto #{$roboto-variant}"; // "Roboto Mono"
|
1.2.3. Unquoted不带引号的
一般就是一些字面量,标识符等等, 一般都是以-
或者--
开始
1
2
3
4
5
6
|
@debug bold; // bold
@debug -webkit-flex; // -webkit-flex
@debug --123; // --123
$prefix: ms;
@debug -#{$prefix}-flex; // -ms-flex
|
- boolean值, true 和false不是
- 颜色名称不是
- null不是
not or and
是boolean 操作符,也不算
1.3. Colors颜色
颜色比较简单,一些字面量和函数 hsl, rgb, rgba, hsla
等等都支持为颜色类型
1
2
3
4
5
6
7
|
@debug #f2ece4; // #f2ece4
@debug #b37399aa; // rgba(179, 115, 153, 67%)
@debug midnightblue; // #191970
@debug rgb(204, 102, 153); // #c69
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
@debug hsl(228, 7%, 86%); // #dadbdf
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)
|
Sass提供了很多颜色函数,可以做颜色的变化,深浅等等效果, 参考Sass: sass:color (sass-lang.com)
1.4. Lists
List包含一组相同类型的值,可以用逗号分隔,也可以用空格分隔,或者/
, 并且不需要特殊的括号,任何被上述逗号,或者空格分隔的表达式都是List
当然如果有特殊需要,比如css里的grid-template-columns
(grid-template-columns - CSS: Cascading Style Sheets | MDN (mozilla.org)),可以写成css的[linename2 linename3]
1.4.1. Slash分隔的Lists
比如font的大小,行高可以这样font: 12px/30px
, 或者一个hsl的颜色可以这样hsl(80 100% 50% / 0.5)
, 尽管如此,
尽量不要使用/
来分隔list,因为过去/
表示除法,现在用math.div()
,如果需要用slash分隔list,用list.slash()
1.4.2. 按索引取值
list.nth($list, $n)
function
1
2
|
@debug list.nth(10px 12px 16px, 2); // 12px
@debug list.nth([line1, line2, line3], -1); // line3
|
1.4.3. 迭代
用@each
rule
1
2
3
4
5
6
7
8
9
|
$sizes: 40px, 50px, 80px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
width: $size;
}
}
|
1.4.4. 添加
list.append($list, $val)
function
1
2
|
@debug append(10px 12px 16px, 25px); // 10px 12px 16px 25px
@debug append([col1-line1], col1-line2); // [col1-line1, col1-line2]
|
注意:sass里的list是不可变的,添加产生的是一个新的变量
1.4.5. 查找
获取索引 list.index($list, $value)
function
1
2
3
|
@debug list.index(1px solid red, 1px); // 1
@debug list.index(1px solid red, solid); // 2
@debug list.index(1px solid red, dashed); // null
|
如果不存在,就返回的是null
1
2
3
4
5
6
7
8
9
10
11
|
@use "sass:list";
$valid-sides: top, bottom, left, right;
@mixin attach($side) {
@if not list.index($valid-sides, $side) {
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
}
// ...
}
|
1.4.6. 不可变
虽然不可变,但是原始变量标识符是可以重新赋值的,所以如果有编辑list的操作,一定要重新赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@use "sass:list";
@use "sass:map";
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
@function prefixes-for-browsers($browsers) {
$prefixes: ();
@each $browser in $browsers {
$prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser));
}
@return $prefixes;
}
@debug prefixes-for-browsers("firefox" "ie"); // moz ms
|
1.4.7. 参数里的list
前面的篇章里关于@mixin
里有讲到,我们可以通过将key
的列表取出,来进一步获取参数中的每一个key,value
如下面的例子,利用meta.keywords
函数将可变参数键值对进行解构,这里有个细节,就是在已知数量的情况下,可以命名参数并解构,在上一篇@each
的章节里有详细介绍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@use "sass:meta";
@mixin syntax-colors($args...) {
@debug meta.keywords($args);
// (string: #080, comment: #800, variable: #60b)
@each $name, $color in meta.keywords($args) {
pre span.stx-#{$name} {
color: $color;
}
}
}
@include syntax-colors(
$string: #080,
$comment: #800,
$variable: #60b,
)
|
1.5. Maps
键值对,形式为(<expression>: <expression>, <expression>: <expression>)
list和map有相同之处,他们的实现中有关联,比如(1:2, 3:4)
其实在list里表现为(1 2, 3 4)
1.5.1. 获取value
map.get($map, $key)
function
1
2
3
4
|
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
@debug map.get($font-weights, "medium"); // 500
@debug map.get($font-weights, "extra-bold"); // null
|
1.5.2. 迭代
同样用@each
可以用于循环map
1
2
3
4
5
6
7
8
9
|
$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f");
@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}
|
1.5.3. 添加
map.set($map, $key, $value)
function
1
2
3
4
5
6
7
8
|
@use "sass:map";
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
@debug map.set($font-weights, "extra-bold", 900);
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)
@debug map.set($font-weights, "bold", 900);
// ("regular": 400, "medium": 500, "bold": 900)
|
1.5.4. 合并
1
2
3
4
5
6
7
|
@use "sass:map";
$light-weights: ("lightest": 100, "light": 300);
$heavy-weights: ("medium": 500, "bold": 700);
@debug map.merge($light-weights, $heavy-weights);
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
|
合并时, 相同的key会被后者替换
1
2
3
4
5
6
|
@use "sass:map";
$weights: ("light": 300, "medium": 500);
@debug map.merge($weights, ("medium": 700));
// ("light": 300, "medium": 700)
|
1.5.5. 不可变
同样map也是不可变的,更新,添加,合并都会产生新的map
1
2
3
4
5
6
7
8
9
10
11
|
@use "sass:map"
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)
@mixin add-browser-prefix($browser, $prefix)
$prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global
@include add-browser-prefix("opera", o)
@debug $prefixes-by-browser
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)
|
1.5.6. 注意事项
尽量不要用没有引号的值做key
1.6. null空值
null
是空值类型的唯一值,通常也作为参数返回,表示没有任何值
1
2
3
4
5
6
|
@use "sass:map";
@use "sass:string";
@debug string.index("Helvetica Neue", "Roboto"); // null
@debug map.get(("large": 20px), "small"); // null
@debug &; // null
|
null在编译css的时候,通常被忽略掉
1
2
3
4
5
6
7
8
9
10
11
|
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
h3 {
font: 18px bold map-get($fonts, "sans");
}
// 得到
h3 {
font: 18px bold;
}
|
属性的值如果为null,编译时,整个属性会被忽略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
h3 {
font: {
size: 18px;
weight: bold;
family: map-get($fonts, "sans");
}
}
// 生成
h3 {
font-size: 18px;
font-weight: bold;
}
|
null是假性的, 只有false和null是假性, 其它任何值,空字符串,0,空list和空map等等都是true,这是sass和别的语言不一样的地方
1.7. ture and flase
和其它语言一样,boolean类型可以用来比较,可以用来判断如>=
之类的关系正确性, 也可以作为一些方法如math.comparable()
和map.has-key()
的返回值
1
2
3
4
5
6
|
@use "sass:math";
@debug 1px == 2px; // false
@debug 1px == 1px; // true
@debug 10px < 3px; // false
@debug math.comparable(100px, 3in); // true
|
注意:在sass里, 只有false和null为假, 其它的都是真,包括空字符串和0,这一点和大部分语言都不一样
1.7.1. 操作符
and or not
1
2
3
4
5
6
7
8
|
@debug true and true; // true
@debug true and false; // false
@debug true or false; // true
@debug false or false; // false
@debug not true; // false
@debug not false; // true
|
1.7.2. 一些使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@mixin avatar($size, $circle: false) {
width: $size;
height: $size;
@if $circle {
border-radius: $size / 2;
}
}
.square-av {
@include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px, $circle: true);
}
|
在if
有一种特殊用法,可以返回值, 如果true返回第二个参数,如果false返回第三个参数
1
2
|
@debug if(true, 10px, 30px); // 10px
@debug if(false, 10px, 30px); // 30px
|
1.8. function
函数类型的值是比较特殊的值,在一些脚本语言,和真正面向对象的语言里非常常见, 函数在编译后也会有引用,所以函数也可以作为值来进行逻辑处理
因为函数 也是值,所以同样可以放到maps和lists里
可以通过meta.get-function()
来获取函数引用, 然后用 meta.call()
来调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@use "sass:list";
@use "sass:meta";
@use "sass:string";
/// Return a copy of $list with all elements for which $condition returns `true`
/// removed.
@function remove-where($list, $condition) {
$new-list: ();
$separator: list.separator($list);
@each $element in $list {
@if not meta.call($condition, $element) {
$new-list: list.append($new-list, $element, $separator: $separator);
}
}
@return $new-list;
}
$fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif;
content {
@function contains-helvetica($string) {
@return string.index($string, "Helvetica");
}
font-family: remove-where($fonts, meta.get-function("contains-helvetica"));
}
|
2. 操作符
2.1. 简介
==
and !=
比较是否相同
+
, -
, *
, /
, and %
数学计算
<
, <=
, >
, and >=
比较大小
and
, or
, and not
条件关系
+
, -
, and /
也可以用来字符串连接
sass遵循标准的操作符优先级顺序,参考Order of operations - Wikipedia
- 一元操作符
not
, +
, -
, and /
.
- The
*
, /
, and %
operators.
- The
+
and -
operators.
- The
>
, >=
, <
and <=
operators.
- The
==
and !=
operators.
- The
and
operator.
- The
or
operator.
- The
=
operator, when it’s available.
所以这里就不做介绍了,有任何一门语言基础的应该都能理解
2.2. Equality 比较
- 数值
- 字符串
- 颜色
- list
- map
- boolean
- 函数引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@debug 1px == 1px; // true
@debug 1px != 1em; // true
@debug 1 != 1px; // true
@debug 96px == 1in; // true
@debug "Helvetica" == Helvetica; // true
@debug "Helvetica" != "Arial"; // true
@debug hsl(34, 35%, 92.1%) == #f2ece4; // true
@debug rgba(179, 115, 153, 0.5) != rgba(179, 115, 153, 0.8); // true
@debug (5px 7px 10px) == (5px 7px 10px); // true
@debug (5px 7px 10px) != (10px 14px 20px); // true
@debug (5px 7px 10px) != (5px, 7px, 10px); // true
@debug (5px 7px 10px) != [5px 7px 10px]; // true
$theme: ("venus": #998099, "nebula": #d2e1dd);
@debug $theme == ("venus": #998099, "nebula": #d2e1dd); // true
@debug $theme != ("venus": #998099, "iron": #dadbdf); // true
@debug true == true; // true
@debug true != false; // true
@debug null != false; // true
@debug get-function("rgba") == get-function("rgba"); // true
@debug get-function("rgba") != get-function("hsla"); // true
|
2.3. Relational 大小关系
1
2
3
4
|
@debug 100 > 50; // true
@debug 10px < 17px; // true
@debug 96px >= 1in; // true
@debug 1000ms <= 1s; // true
|
自动单位转换
1
2
|
@debug 100 > 50px; // true
@debug 10px < 17; // true
|
不可比较的单位会报错
2.4. Numeric 数值计算
2.4.1. 单位转换
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@debug 10s + 15s; // 25s
@debug 1in - 10px; // 0.8958333333in
@debug 5px * 3px; // 15px*px
@debug 1in % 9px; // 0.0625in
// 自动识别
@debug 100px + 50; // 150px
@debug 4s * 10; // 40s
// 无法转换的会报错
@debug 100px + 10s;
// ^^^^^^^^^^^
// Error: Incompatible units px and s.
|
2.4.2. 一元操作符
紧跟-
或者+
, +不变, -
为负数
-
as part of an identifier. The only exception are units; Sass normally allows any valid identifier to be used as an identifier, but units may not contain a hyphen followed by a digit.
-
表达式之间没有空格,被视为减法
-
加上一个数字开头,被视为是一个负数
-
两个数字之前,不考虑空格,被视为减法
-
在非数字之前,被视为一元否定
2.4.3. Division除法
在sass里非常特殊,/
通常有别的用途,比如分隔符, 用 math.div()
来表示除法
注意下面的一些特殊情况
- 任何表达式都不是数值类型
- 结果存储在变量中或者作为返回值
- 被括号直接包裹
- 结果作为计算的另一个组成部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@use "sass:list";
@debug 15px / 30px; // 15px/30px
@debug (10px + 5px) / 30px; // 0.5
@debug list.slash(10px + 5px, 30px); // 15px/30px
$result: 15px / 30px;
@debug $result; // 0.5
@function fifteen-divided-by-thirty() {
@return 15px / 30px;
}
@debug fifteen-divided-by-thirty(); // 0.5
@debug (15px/30px); // 0.5
@debug (bold 15px/30px sans-serif); // bold 15px/30px sans-serif
@debug 15px/30px + 1; // 1.5
|
如果明确是分隔符,sass:list
的slash
1
|
@debug list.slash(10px + 5px, 30px); // 15px/30px
|
2.4.4. 单位
单位可以相同,可以不通, 除法的时候, 一般都可以将数值和时间作为任意一边的表达式
1
2
3
4
5
6
7
8
9
|
@debug 4px * 6px; // 24px*px (read "square pixels")
@debug math.div(5px, 2s); // 2.5px/s (read "pixels per second")
// 3.125px*deg/s*em (read "pixel-degrees per second-em")
@debug 5px * math.div(math.div(30deg, 2s), 24em);
$degrees-per-second: math.div(20deg, 1s);
@debug $degrees-per-second; // 20deg/s
@debug math.div(1, $degrees-per-second); // 0.05s/deg
|
如果分子分母是兼容单位,那么单位就可以换算并抵消
做了一个实验
1
2
3
4
|
@use "sass:math";
@debug math.div(96px, 1in)
// DEBUG: 1
|
2.4.5. 补充下css的单位
参考:
绝对单位
Unit |
Description |
cm |
centimeters |
mm |
millimeters |
in |
英寸inches (1in = 96px = 2.54cm) |
px * |
像素pixels (1px = 1/96th of 1in) |
pt |
点points (1pt = 1/72 of 1in) |
pc |
派卡picas (1pc = 12 pt) |
相对单位
Unit |
Description |
em |
Relative to the font-size of the element (2em means 2 times the size of the current font) |
ex |
Relative to the x-height of the current font (rarely used) |
ch |
Relative to the width of the “0” (zero) |
rem |
Relative to font-size of the root element |
vw |
Relative to 1% of the width of the viewport* |
vh |
Relative to 1% of the height of the viewport* |
vmin |
Relative to 1% of viewport’s* smaller dimension |
vmax |
Relative to 1% of viewport’s* larger dimension |
% |
Relative to the parent element |
2.4.6. 注意事项
-
很多字面量标识符和字符串会用到,所以特殊场景不一定是减号
1
2
3
4
5
6
7
8
|
@debug a-1; // a-1
@debug 5px-3px; // 2px
@debug 5-3; // 2
@debug 1 -2 3; // 1 -2 3
$number: 2;
@debug 1 -$number 3; // -1 3
@debug 1 (-$number) 3; // 1 -2 3
|
尽量在定义的时候不要用差值来表示数值单位, 直接在变量定义的时候带上单位,前面也有提到过,参考2.1.2. 注意事项
2.5. String 字符串操作符
2.5.1. 字符串连接
1
2
3
|
@debug "Helvetica" + " Neue"; // "Helvetica Neue"
@debug sans- + serif; // sans-serif
@debug sans - serif; // sans-serif
|
如果有其它类型值和字符串进行操作,同样也是连接操作
1
2
|
@debug "Elapsed time: " + 10s; // "Elapsed time: 10s";
@debug true + " is a boolean value"; // "true is a boolean value";
|
2.5.2. 一元操作符
/<expression>
返回一个没有引号的字符串,以/
开头
-<expression>
返回一个没有引号的字符串,以-
开头
1
2
|
@debug / 15px; // /15px
@debug - moz; // -moz
|
2.6. Boolean 布尔操作符
特殊一点,不是用符号,是用下面的关键字
not <expression>
取反
<expression> and <expression>
都为true则是true, 有一个false就返回false
<expression> or <expression>
有一个true返回true, 两个false就返回false
1
2
3
4
5
6
7
8
|
@debug not true; // false
@debug not false; // true
@debug true and true; // true
@debug true and false; // false
@debug true or false; // true
@debug false or false; // false
|
任何可以使用boolean类型的地方,都可以用其它值类型代替,
上一篇也说过除了false
和null
,其它任何都为true
,包括0, 空字符串