文档 1
链接: https://sass-lang.com/documentation/
文档整体包括:
- 语法
- Style Rules
- 变量
- 插值
- At-Rules
- Values
- 运算
- 内置模块
- Breaking Changes
- 命令行
- JavaScript API
1. 语法
Sass 有两种语法:
- 与 CSS 兼容的 SCSS 语法. 其中所有的 CSS 都是合法的 SCSS 语法. 后缀用
.scss
- 缩进语法, 后缀用
.sass
1.1 样式表的结构
Sass 样式表主要由语句 (Statements) 和表达 (Expression) 式构成.
语句
Sass 的样式表由语句构成, 有的语句带有由花括号构成的块. 语句最后会生成 CSS.
实际上就是 Sass 的语法构成, 形如:
选择器 { 样式属性: 样式值; ... }
但 Sass 中选择器允许嵌套. 从语法上, 统一将其称为语句.
通用语句
可用于 Sass 样式表的任何位置. 包括:
- 变量声明. 例如:
$var: value
. - 流程控制 at-rules, 例如:
@if
,@each
. @error
,@warn
, 以及@debug
规则.
CSS 语句
可以看出 Scss 是 CSS 的超集, 因此 CSS 语句也是合法的 Sass 语句. 它可以使用在任意位置, 除了 @function
中.
包括:
- 样式规则 (style rule), 实际上就是选择器, 例如
h1 { ... }
. - CSS 的
at-rules
, 例如:@media
,@font-face
. - 混入, 例如:
@include
. @at-root
顶级语句
该声明只允许定义在样式文件的顶部级别. 或是嵌套在 CSS 声明的顶级位置.
- 模块加载,
@use
- 导入,
@import
- 混入定义,
@mixin
- 函数定义,
@function
其他语句
- 标准的 CSS 样式属性语句, 即
样式属性: 样式值
. @extend
规则.
表达式
表达式是可以放在属性名右侧, 或变量声明右侧的数据.
逻辑上与编程结构中一样, 就是最终会成为一个数据的东西.
- 每一个表达式最终会得到一个值.
- CSS 的属性值是合法的 Sass 表达式, 反过来不一定.
将 Sass 表达式称为 SassScript. 它常用于 参数传入到 混入或函数中, 或 @if
等规则中.
字面量
这是最简单的表达式.
- 数值, 可以带有单位, 例如 12, 或 100px 都是数值.
- 字符串, 有可能带有双引号, 或无双引号. 典型的如
font-family
的值. - 颜色, 可以是井号十六进制描述, 或颜色的名字.
- 布尔值, 即
true
或false
. - null, 它是单例的.
- 值列表, 形式上可以是: 空格分隔, 逗号分隔, 有可能被置于方括号中, 也可能没有中括号.
- Maps. 形如
("key": value, ...)
运算符
Sass 中定义了可用于数值的运算符.
==
和!=
.+
,-
,*
,/
, 以及%
.<
,<=
,>
, 和>=
.and
,or
, 和not
. Sass 中将所有的值都视为true
, 除了false
和null
.+
,-
,/
可以用于字符串连接.(
和)
用于提升运算符优先级.
其他表达式
- 变量
- 函数调用
- 特殊函数
- 父选择器, 例如:
&
!important
, 会被视为没有引号的字符串.
1.2 注释
一般注释语法
// 该注释不会编译到 CSS 中
/* 该注释会被编译到 CSS 中, 但是压缩模式下会移除该注释 */
/* 注释中可以包含插值语法, 例如 1 + 1 = #{ 1 + 1 } */
/*! 该注释会一直保留, 即使是压缩模式 */
文档注释
/// 三斜线为文档注释
///
/// @params {类型} 变量名
/// @return {...} ...
可参考: http://sassdoc.com/annotations/
1.3 特殊函数
CSS 定义了很多函数, 大多数函数可以直接在 Sass 中正常使用. 但有些例外.
主要是带引号和不带引号的字符串引发的问题
url()
该函数是 css 函数, 它支持带引号和不带引号的 url, 但是在 SassScript 中无引号的 url 是不合法的. 因此需要转换.
简单说有三种用法(示例提供)
// url("合法的连接字符串, 其中可以包含插值")
url("#{$roboto-font-path}/Roboto-Thin.woff2")
// url(SassScript 表达式)
url($roboto-font-path + "/Roboto-Light.woff2")
// 特殊函数
url(#{$roboto-font-path}/Roboto-Regular.woff2)
element()
, progid:...()
, 和 expression()
主要是说 #
的含义:
- 可以描述 ID 选择器
- 可以描述颜色值
所以在实际使用中需要特殊转换.
其他略.
2. Style Rules
2.1 概览
样式规则是 Sass 的核心.
这一块实际上就是在描述一般的样式表结构的语法
支持嵌套
构成后代选择器
选择器列表
.s1, .s2 {
.ss1, .ss2 {
}
}
会进行组合排列 (笛卡尔积)
.s1 .ss1, .s1 .ss2, .s2 .ss1, .s2 .ss2 {
}
选择器组合
主要针对 >
, ~
, 和 +
, 可放在父级末尾, 也可以放在子级之前.
高级嵌套
参考父选择器, 此处略.
注意此处对父选择器的引用不构成层级
.err {
color: red;
&--font {
font-size: 1.5rem;
}
}
它目的在于引用 "父级" 选择器的名字, 凡是构成完整标识符的都不会生成层级.
.err {
color: red;
}
.err--font {
font-size: 1.5rem;
}
插值 (这个高级)
结合 @mixin
可以在选择器名字上进行插值表达式. 例如:
@mixin my-bg-color($name: red, $color: red) {
.cus-bg-color-#{$name} {
background-color: $color;
}
}
@include my-bg-color(green, green)
2.2 属性声明
主要说明用于设置样式的属性名. 例如 background-color
等.
插值
属性名允许使用插值的方式来呈现;
@each $i in (1, 2, 3, 4) {
.md-#{$i} {
width: #{$i}px;
}
}
嵌套
两个方便:
- 嵌套构成后台选择器
- 带有冒号的语法
形如:
background-color: ...
background-size: ...
可以写成:
background: {
color: ...
size: ...
}
隐藏声明
在构建时, 属性值为 null 或空无引号字符串时不会被 Sass 编码到 CSS 中.
这一特性对编写 Sass 技巧很方便.
.box {
border-color: red;
border-width: null;
}
自定义属性 (暂略)
CSS 自定义属性即所谓的 CSS 变量.
CSS 变量:
- 由
--
开头, 形如--标识符: 值
来定义. 通常变量定义在:root
中.- 使用时使用
var()
来获得标识符对应的值.例如:
:root { --color: red; } .selector { color: var(--color); }
Sass 在解析的时候不会解析, 因此在需要数据的位置应该使用插值语法.
但是插值语法会移除引号, 所以如果值中含有双引号, 可以使用 sass:meta
下的 inspect
函数.
2.3 父选择器
即 &
. 在嵌套模式下, 用于引用父选择器. 常用与:
- 伪选择器
- 构造选择器层级
- 构造表达式. 逻辑上类似于插值
与 SassScript 合用
高级用法, 暂略.
2.4 站位选择器
实际上就是 @extend
用法.
语法:
- 用
%
前缀定义样式表. - Sass 编译不会将其写入 CSS 中.
- 在需要的位置使用
@extend
, 会使用当前选择器的名字来引用该 占位选择器 的样式表.
不使用就不会被编译:
使用的时候会生成:
生成的选择器, 即为使用 @extend
上下文的选择器.
3. 变量
声明语法:
$变量名: 值;
注意 Sass 变量名中的中划线与下划线视为一样的 (历史原因).
在 Scss 代码中改变变量的值, 按照从上至下的方式解析取 Sass 变量的值 (即改变的值只影响后使用的变量).
3.1 默认值
在模块中定义的变量, 在模块外允许对其修改值, 而模块内的变量可以含有默认值.
# 定义模块中的变量默认值, 用 !default 来标识默认值
$变量: 值 !default;
# 使用模块, 用 with() 覆写变量值
@use '模块' with (
$变量: 新值, ...
)
3.2 内置变量
内置模块中的变量值不允许修改.
3.3 作用域
逻辑上与块级作用于一样.
隐藏全局变量
逻辑上与块级作用域一样.
特殊性:
- 如果某一样式表块中有与全局同名的变量, 那么是两个变量
- 如果子作用于需要修改全局作用于的变量, 使用
!global
后缀
流程控制作用域
流程控制所在块中的变量既是当前流程控制所在层级的变量. 即流程控制的语法块, 不会起新作用域.
需要注意的是, 流程控制中使用的, 但外部没有的变量会被忽略.
特殊函数
meta.variable-exists()
判断是否存在局部变量meta.global-variable-exists()
判断是否存在某全局变量
Scss 不允许使用变量值来进行插值定义新变量, 即下面报错:
$color: red;
$font-#{$color}: $color
可以曲线救国, 定义一个 map
.
@use "sass:map"
$theme-colors: (
"success": green,
"error": red,
);
.alert {
color: map.get($theme-colors, "error")
}
4. 插值
语法为 #{ }
, 几乎可以用在任何位置.
需要注意的是:
- 插值表达式得到的结果为不带引号的字符串.
- 不适用于数学运算, 插值表达式返回的是字符串, 不用于数学计算.
- Sass 内置了涉及单位的算术运算的功能. 推荐在定义变量的时候带上单位. 这样编译出现错误更为友好.
考虑到 Sass 插值会自动移除引号, 使用 string.unquote()
函数语义更明晰.
5. At-Rules (at-模块)
Sass 文件一开始会有很多 at-rule.
@use
从另一个 Sass 文件中导入 mixin, function, variable 等. 或从多个样式表中合并 CSS.@forward
加载 Sass 样式表, 并将其作为 mixin, function, 或 variable 的样式表, 用于其他文件在@use
中导入.@import
扩展了 CSS, 用于从其他 Sass 样式表中导入 样式, mixin, function 和 variable 等.@mixin
和@include
可以快速的方便的使用样式片段.@function
定义自定义函数, 可以用在 Sass 表达式中.@extend
允许选择器从其他样式表中继承样式.at-root
将样式添加到 CSS 文档的根部.@error
获得一个错误消息, 并引发编译失败 (会结束编译).@warn
打印一个警告信息, 但不会引发异常.@debug
用于调试的信息输出.- 流程控制, 例如:
@if
,@each
, 以及@while
.
5.1 @use
基本语法:
@use "url";
url
对应另一个 scss
文件, 被称之为模块. 模块命名带有下划线前缀 (不被编译).
@use
不会出现重复导入问题.
加载成员
@use
语法后跟的 url
即文件名, 可以将文件名作为命名空间, 来引用文件下的成员. 例如 mixin
等.
可以使用:
namespace.variable
namespace.function()
namespace.mixin()
来引入成员, 命名空间默认为 url
最后一个层级的名字 (即, 文件名).
@use
具有文件作用域, 当前文件导入的成员只允许在当前文件中使用. 其他文件需要使用则重新 @use
.
这个规则优于
@import
, 从而避免带有各种前缀的长命名形式.
自定义命名空间名
默认命名空间为 @use <"url">;
中 url
的最后一个层级的名字. 可以使用 as
语法自定义命名空间.
@use "..." as namespace;
也可以使用 *
来移除命名空间.
// style.scss
@use "base" as *;
// 此时直接使用 `base` 中的成员, 不用带有命名空间, 好似两个文件合并在一起一样.
私有成员
使用 -
或 _
开头的成员为私有成员. 例如:
$-privateVariable1
$_privateVariable2
配置信息
即在加载模块的时候, 重新为变量赋值. 要实现该特性需要:
- 模块中定义变量时, 使用
!default
作为后缀. @use
的时候, 带有with ()
表达式, 为变量重新赋值.
使用 Mixin (使用技巧)
当需要一次配置多个变量的时候, 建议使用 mixin
等功能.
重新赋值
模块中定义的变量, 在导入模块后, 允许使用 namespace.variable
来重新赋值. 注意, 即修改原来的值.
math
模块中的$pi
不允许重新赋值.
模块查找
Sass 会自动查找对应的文件, 不用在编写时写上 文件的后缀.
注意
- Sass 使用 url, 而不是 path, 即需要使用斜线, 而不是反斜线.
- Sass 优先使用相对于当前文件位置的文件.
- 部分文件, 即下划线开头的文件, 不会被编译, 默认供其他文件加载.
- 默认文件, 使用
index
作为文件名, 在使用文件夹作为路径时, 会被默认加载.
加载 CSS
语法无差别. 也不用考虑后缀.
与 @import
的不同
@use
设计出来是用于替换 @import
的.
@use
具有文件作用域, 不会将导入的数据放到全局作用域中.@use
只会加载依次文件, 不会重复导入.@use
只允许出现在文件顶部, 不允许嵌套于某样式表内.- 每一个
@use
只能有一个url
. @use
必须使用引号包裹的url
.
5.2 @forward
用于组合多个 Sass 样式表模块为一个模块文件. 用于其他样式表来加载.
语法:
@forward "url";
它将模块组织在一起, 并将成为设置为 public
的 (就好像写在当前文件中一样).
除此之外, @forward
可以控制隐藏成员. 配置成员等.
针对 CSS 的导入, 逻辑上与 @use
用法一样.
添加前缀
使用语法:
@forward "url" as 前缀-*;
该语法逻辑上:
- 导入
"url"
中的成员到当前文件 (直接使用成员名) - 通过
as
和*
来为成员名添加对应的前缀 (*
带表成员名) - 在另一个文件中使用
@use
加载当前文件, 即可使用新名字.
控制隐藏
可以使用 hide
与 show
语法来控制影藏与显示.
@forward "url" hide <name>, ...; // 表示隐藏给定的, 其他都导出.
@forward "url" show <name>, ...; // 表示显示给定的, 其他都隐藏.
配置模块
用法与 @use
中的配置一样, 不同是, @forward
允许变量带有 !default
后缀, 表示该变量可以被下游模块再次改变.
@forward "url" with (
$variable: value !default, ...
);
5.3 @import
(官方不推荐, 因此略)
Sass 扩展了 CSS 中的 @import
, 让他可以导入 CSS 也可以导入 Sass. 来导入 mixin, function, variable, 以及组合他们.
不同于 CSS 的 @import
是在页面解析阶段, 通过 HTTP 来加载 CSS 模块.
而 Sass 的 @import
完全是在编译阶段完成的.
使用语法与 CSS 兼容. 扩展的是:
- 支持一个
@import
导入多个文件, 只需要使用逗号分割即可. @import
的url
不需要强制使用引号.
Sass 官方不推荐使用
@import
, 可能会从后续版本中移除.
5.4 @mixin
和 @include
使用 @mixin
定义样式表片段. 使用 @include
导入样式片段, 并完全替换该位置的内容.
@mixin
语法:
@mixin 名字 (参数) {
样式表 ...
}
参数是可选的, 如果不需要参数可以省略括号.
@include
语法:
@include 名字 (参数);
如果没有参数可以省略, 括号可省略.
参数
mixin 可以带有参数:
- 参数可有, 也可无. 无参数时可以省略括号.
- 参数可以带有默认值, 带有默认值,
@include
可以不传参. - 参数传递可以有两种方法: 按照位置依次传入, 使用命名参数方式传入 (语法形式与定义默认参数一样).
- Sass 中支持任意参数.
任意参数
使用 ...
语法:
@mixin 名字 (参数...) {
...
}
任意参数逻辑上与 C#
中的 params
, 与 JavaScript
ES6
中的 前置 ...
逻辑一样.
表示该 mixin 可以接收任意个参数, 并以列表形式被 参数名 所引用.
并且该参数只允许放在末尾.
使用技巧
- 使用
@for 迭代变量 from 0 to length(参数) { ... }
来访问传入的每一个参数的索引. - 使用
nth(参数, 索引)
来访问参数列表中对应的传入值, 注意索引从 1 开始.
使用命名参数
- 使用
meta.keywords(参数)
来获得 键值对 集合. 逻辑上类似于C#
中的KeyValuePair
. - 使用
@each
来遍历键值对集合.
需要导入
sass:meta
模块.
传入多个参数
类似于 JavaScript 中的参数解构.
将列表作为参数传入 @mixin
中使用后置 ...
, 来实现解构.
一个使用技巧
利用参数可以对某具体函数等解构进行包装:
@mixin btn($args...) {
@warn "btn() mixin 已不推荐使用, 请替换为 button().";
@include button($args...);
}
内容块 (Content Blocks)
逻辑上类似于插槽, 专门用于处理大块的样式作为参数使用. 用法:
- 定义
@mixin
, 并在其内部使用关键字@content
作为占位符定义内容块. - 在使用的时候
@include
导入时, 带上花括号, 其中编写样式表. - 编译时, 会将
@include
后的块, 直接替换到对应 位置导入@mixin
中的占位符位置的@content
处.
语法上, 允许有多个
@content
, 多个@content
会同时提供样式.
注意, 内容块是词法作用域.
为内容块传参
mixin
可以为自己的 content
传参. 语法形式与为 mixin
传参一样:
@content (参数列表);
使用 @include
导入 mixin
的时候 可以使用 using
语法来接受参数.
逻辑与 Vue 中作用域插槽一个逻辑.
上述代码与上一个词法作用域的代码类似, 但逻辑不同.
- 词法作用域示例下, block 中只可以看到全局作用域的
$color
- 而传参示例中, block 中看到的
$color
实际上是由mixin
提供给@content
的.
必要时可以将参数定义为
map
, 来提升灵活性.
5.5 @function
与通常意义的函数一样, 用于定义复杂的运算过程. 来支持复用.
- 函数中只允许使用通用语句 (变量, 流程控制, 警告, debug 和错误提示).
- 使用
@return
返回数据.
语法形式:
@function 函数名 (参数列表) {
...
@return 要返回的数据;
}
函数的调用与发与 CSS 中的调用语法一样.
注意函数名为 Sass 标识符, 也就是说视中划线 (
-
) 与下划线 (_
) 是一样的.
参数 (与 @mixin
参数用法几乎一样, 略)
参数内容包括:
- 语法
- 可选参数
- 关键字参数用法 (具名参数)
- 多个参数 (
...
语法) - 多个具名参数
- 传入多个参数
@return
逻辑与一般编程语言中的 return
一样. 需要注意:
- Sass 中函数是用于封装复杂计算的, 因此它必须含有
@return
. 这一点与 Basic 语言类似, 有函数与过程之分. 更像是这里的函数. - 函数中
@return
用于结束函数的执行, 可以有多个@return
, 可以置于@if
块中. 这类逻辑与编程语言中的一致.
其他函数
Sass 提供了内置模块. 提供了很多函数. 这里暂时不考虑.
纯 CSS 函数
任何函数的调用最终会转换为 CSS. 用户定义的函数与 Sass 内置函数会在编译过程中转换为 CSS, 而其他函数会转换为 CSS 函数, 在 CSS 解析时, 在浏览器中被执行.
因为所有的未知函数都会被转换为 CSS 函数. 作者建议使用 CSS Linter 来检查 CSS. 确保函数的准确.
5.6 @extend
使用场景:
- 有一个样式表.
- 新页面(模块), 基于该样式表进行设计, 但包含自己的样式.
可以将样式表定义为公共的样式模块.
然后在需要的选择器中使用 @extend
, 让对应选择器具有该样式.
重点是让这个选择器, 具有了该样式.
它是如何起作用的
不同于 @mixin
的直接插入, @extend
采用的是选择器继承 (重点是人清选择器是什么).
生成样式选择器的算法相对来说比较复杂:
- 不违背元素的嵌套规则.
- 尽可能生成多的可能性, 会交叉生成选择器.
- 尽可能会简化选择器的层级.
占位选择器
使用 %
开头的选择器名. 专门用于被 @extend
, 本身不会被编译到 CSS 中.
注意站位选择器不允许直接封装为模块使用.
一些注意:
- 派生选择器只会修改上游的选择器.
- 派生的选择器时如果选择器不存在会报错, 可以在后加上
!optional
来忽略错误. - 选择扩展还是混入? 经验上如果是语义类选择器时, 使用扩展更好.
限制
熟练后再考虑, 略
5.7 @error
一般用在流程控制中, 例如函数中等. 用于抛出错误信息. 逻辑上对标抛出异常. 会阻塞编译.
语法:
@error 表达式;
5.8 @warn
警告信息, 用法与 @error
, 但不会阻塞编译, 仅会输出警告消息.
语法:
@warn 表达式;
注意在命令行中会显示 debug 信息, 而在 VSCode 插件中不会显示 debug 信息
5.9 @at-root
(略)
一般语法写成:
@at-root 选择器 {
...
}
让其内的样式表置于文档根部, 而不是嵌套于某个选择器下. 属于高级用法. 暂略.
https://sass-lang.com/documentation/at-rules/at-root/
5.10 流程控制
涉及到:
@if
与@else
@each
@for
@while
@if
与 @else
语法:
@if 表达式 {
} @else if 表达式 {
} @else {
}
@each
用于遍历集合 (list) 与键值对 (map)
语法:
// 遍历集合
@each $项 in $集合 {
...
}
// 遍历键值对
@each $key, $val in $键值对 {
...
}
支持遍历列表的列表(解构语法)
$icons:
"eye" "\f112" 12px,
"start" "\f12e" 16px,
"stop" "\f12f" 10px;
@each $name, $glyph, $size in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
font-size: $size;
}
}
@for
遍历数字, 有两个语法:
@for $迭代变量 from 起始数 to 终止数 {
...
}
@for $迭代变量 from 起始数 through 终止数 {
...
}
to
和 through
的区别是, to
取不到右侧值, through
可以取到.
@while
语法:
@while 表达式 {
// ... 表达式为 false 跳出循环
}
5.11 来自 CSS 的 at 指令
暂略
https://sass-lang.com/documentation/at-rules/css/