jk's notes
  • 文档 1

文档 1

链接: https://sass-lang.com/documentation/

文档整体包括:

  1. 语法
  2. Style Rules
  3. 变量
  4. 插值
  5. At-Rules
  6. Values
  7. 运算
  8. 内置模块
  9. Breaking Changes
  10. 命令行
  11. 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 {
    
}
选择器组合

主要针对 >, ~, 和 +, 可放在父级末尾, 也可以放在子级之前.

image-20230712152017246

高级嵌套

参考父选择器, 此处略.

注意此处对父选择器的引用不构成层级
.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)

image-20230712152530575

2.2 属性声明

主要说明用于设置样式的属性名. 例如 background-color 等.

插值

属性名允许使用插值的方式来呈现;

@each $i in (1, 2, 3, 4) {
  .md-#{$i} {
    width: #{$i}px;
  }
}

image-20230714104949515

嵌套

两个方便:

  • 嵌套构成后台选择器
  • 带有冒号的语法

形如:

background-color: ...
background-size: ...

可以写成:

background: {
    color: ...
    size: ...
}

image-20230714105327697

隐藏声明

在构建时, 属性值为 null 或空无引号字符串时不会被 Sass 编码到 CSS 中.

这一特性对编写 Sass 技巧很方便.

.box {
  border-color: red;
  border-width: null;
}

image-20230714105621309

自定义属性 (暂略)

CSS 自定义属性即所谓的 CSS 变量.

CSS 变量:

  1. 由 -- 开头, 形如 --标识符: 值 来定义. 通常变量定义在 :root 中.
  2. 使用时使用 var() 来获得标识符对应的值.

例如:

:root {
	--color: red;
}
.selector {
    color: var(--color);
}

Sass 在解析的时候不会解析, 因此在需要数据的位置应该使用插值语法.

但是插值语法会移除引号, 所以如果值中含有双引号, 可以使用 sass:meta 下的 inspect 函数.

2.3 父选择器

即 &. 在嵌套模式下, 用于引用父选择器. 常用与:

  • 伪选择器
  • 构造选择器层级
  • 构造表达式. 逻辑上类似于插值

与 SassScript 合用

高级用法, 暂略.

2.4 站位选择器

实际上就是 @extend 用法.

语法:

  1. 用 % 前缀定义样式表.
  2. Sass 编译不会将其写入 CSS 中.
  3. 在需要的位置使用 @extend, 会使用当前选择器的名字来引用该 占位选择器 的样式表.

不使用就不会被编译:

image-20230714112328728

使用的时候会生成:

image-20230714112552027

生成的选择器, 即为使用 @extend 上下文的选择器.

3. 变量

声明语法:

$变量名: 值;

注意 Sass 变量名中的中划线与下划线视为一样的 (历史原因).

在 Scss 代码中改变变量的值, 按照从上至下的方式解析取 Sass 变量的值 (即改变的值只影响后使用的变量).

3.1 默认值

在模块中定义的变量, 在模块外允许对其修改值, 而模块内的变量可以含有默认值.

# 定义模块中的变量默认值, 用 !default 来标识默认值
$变量: 值 !default;
# 使用模块, 用 with() 覆写变量值
@use '模块' with (
	$变量: 新值, ...
)

3.2 内置变量

内置模块中的变量值不允许修改.

3.3 作用域

逻辑上与块级作用于一样.

隐藏全局变量

逻辑上与块级作用域一样.

特殊性:

  1. 如果某一样式表块中有与全局同名的变量, 那么是两个变量
  2. 如果子作用于需要修改全局作用于的变量, 使用 !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

配置信息

即在加载模块的时候, 重新为变量赋值. 要实现该特性需要:

  1. 模块中定义变量时, 使用 !default 作为后缀.
  2. @use 的时候, 带有 with () 表达式, 为变量重新赋值.

image-20230718094552949

使用 Mixin (使用技巧)

当需要一次配置多个变量的时候, 建议使用 mixin 等功能.

image-20230718095419373

重新赋值

模块中定义的变量, 在导入模块后, 允许使用 namespace.variable 来重新赋值. 注意, 即修改原来的值.

math 模块中的 $pi 不允许重新赋值.

image-20230718095359497

模块查找

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 前缀-*;

该语法逻辑上:

  1. 导入 "url" 中的成员到当前文件 (直接使用成员名)
  2. 通过 as 和 * 来为成员名添加对应的前缀 (* 带表成员名)
  3. 在另一个文件中使用 @use 加载当前文件, 即可使用新名字.

image-20230718110135505

控制隐藏

可以使用 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 名字 (参数);

如果没有参数可以省略, 括号可省略.

image-20230718113407739

参数

mixin 可以带有参数:

  • 参数可有, 也可无. 无参数时可以省略括号.
  • 参数可以带有默认值, 带有默认值, @include 可以不传参.
  • 参数传递可以有两种方法: 按照位置依次传入, 使用命名参数方式传入 (语法形式与定义默认参数一样).
  • Sass 中支持任意参数.
任意参数

使用 ... 语法:

@mixin 名字 (参数...) {
  ...
}

任意参数逻辑上与 C# 中的 params, 与 JavaScript ES6 中的 前置 ... 逻辑一样.

表示该 mixin 可以接收任意个参数, 并以列表形式被 参数名 所引用.

并且该参数只允许放在末尾.

使用技巧
  • 使用 @for 迭代变量 from 0 to length(参数) { ... } 来访问传入的每一个参数的索引.
  • 使用 nth(参数, 索引) 来访问参数列表中对应的传入值, 注意索引从 1 开始.

image-20230718115155670

使用命名参数
  • 使用 meta.keywords(参数) 来获得 键值对 集合. 逻辑上类似于 C# 中的 KeyValuePair.
  • 使用 @each 来遍历键值对集合.

需要导入 sass:meta 模块.

image-20230718115940680

传入多个参数

类似于 JavaScript 中的参数解构.

将列表作为参数传入 @mixin 中使用后置 ..., 来实现解构.

image-20230718124934659

一个使用技巧

利用参数可以对某具体函数等解构进行包装:

@mixin btn($args...) {
  @warn "btn() mixin 已不推荐使用, 请替换为 button().";
  @include button($args...);
}

内容块 (Content Blocks)

逻辑上类似于插槽, 专门用于处理大块的样式作为参数使用. 用法:

  • 定义 @mixin, 并在其内部使用关键字 @content 作为占位符定义内容块.
  • 在使用的时候 @include 导入时, 带上花括号, 其中编写样式表.
  • 编译时, 会将 @include 后的块, 直接替换到对应 位置导入 @mixin 中的占位符位置的 @content 处.

image-20230718125939552

语法上, 允许有多个 @content, 多个 @content 会同时提供样式.

image-20230718141518413

注意, 内容块是词法作用域.

image-20230718141945868

为内容块传参

mixin 可以为自己的 content 传参. 语法形式与为 mixin 传参一样:

@content (参数列表);

使用 @include 导入 mixin 的时候 可以使用 using 语法来接受参数.

逻辑与 Vue 中作用域插槽一个逻辑.

image-20230718142653951

上述代码与上一个词法作用域的代码类似, 但逻辑不同.

  • 词法作用域示例下, 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, 让对应选择器具有该样式.

image-20230718151136973

重点是让这个选择器, 具有了该样式.

它是如何起作用的

不同于 @mixin 的直接插入, @extend 采用的是选择器继承 (重点是人清选择器是什么).

生成样式选择器的算法相对来说比较复杂:

  1. 不违背元素的嵌套规则.
  2. 尽可能生成多的可能性, 会交叉生成选择器.
  3. 尽可能会简化选择器的层级.

占位选择器

使用 % 开头的选择器名. 专门用于被 @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/

Last Updated:
Contributors: jk