Sass 文档笔记
官方文档 https://sass-lang.com
有一些历史笔记, 但每次都整理了一半:
文档分为两个部分:
- 快速开始. 一个涵盖常用功能的简略文档
- 详细文档.
这里首先介绍快速开始的文档内容. 官方地址.
sass
的使用有两种方式:
- 结合前段框架, 例如
vue
、react
等前段框架和构建工具, 以及babel
等插件来编译sass
来生成css
. - 安装本地
sass
工具, 直接编译sass
文件, 来生成css
.
本笔记 (文档) 采用安装本地 sass
工具来生成 css
.
安装语法:
npm i -g sass
安装后即可使用下面命令来编译 sass
来生成 css
. 使用语法:
sass <input>.sass <output>.css
sass
命令带有--watch
选项, 来实时监视文件变化, 进行编译.
也可以使用 VSCode
插件: Live Sass Compiler
. 该插件会在 VSCode
下方工具栏中提供一个开关, 用于实时编译 sass
文件, 来生成 css
.
点击该按钮后, VSCode
会实时监视 scss
格式的文件, 来生成 css
文件.
scss
格式的文件使用与css
类似的语法格式, 采用花括号作为块.
sass
格式的文件使用缩紧来表示块. 其代码逻辑是一样的, 只是描述块的层级关系的语法不同.
快速开始
变量
语法:
$color: red;
- 使用
$
引导标识符来表示变量名. - 使用冒号来进行赋值.
- 需要使用分号结尾.
不同于编程语言中的标识符, 中间允许含有连字符 (-
). 例如 $font-color: red;
.
嵌套
选择器可以嵌套, 用于表示后代选择器. 注意不是子级. 是后代.
允许在后代选择器前使用 &
来引用祖代选择器, 构造子选择器. 例如:
.ul {
& > .li {
// 这是子选择器
}
}
partial 文件
可以翻译为部分文件, 局部文件等.
编译器会编译所有的 .scss
文件. 如果不希望编译, 值希望将其作为逻辑上, 可服用的局部代码, 只需要在前添加下划线作为前缀即可. 编译器会自动跳过该文件.
例如: _partials.scss
文件.
模块
将复用的代码写到单独的文件中 (命名采用 partial
方式, 即下划线开头), 在需要的文件中用 @use
规则导入.
导入模块采用文件名作为命名空间.
@use '文件名';
// 使用 `文件名.成员` 来引用
Mixins
(混入)
@mixin
可以看成一个 CSS
片段, 可以带有参数. 在需要的地方 include 进来即可.
定义语法:
@mixin <名字>([参数]) {
样式表: 值;
...
}
使用的时候, 在需要的地方 @include
即可
@include <名字>([参数]);
混入是将一段
CSS
代码片段, 整个填入@include
的位置.
扩展与继承
Extend/Inheritance
基本逻辑是:
- 定义一个具名样式块, 使用
%
引到 (逻辑上是一个css
块, 预备用于某选择器上). - 然后再需要的选择器中使用
@extend
来引用该样式块. - 会自动生成两个选择器, 来使用该样式.
与
@mixin
的区别是:
@mixin
是整个css
块贴过来, 迁入到@include
的位置.- 继承则是利用选择器的功能, 将
css
片段整合到组合选择器中.
定义语法:
%名字 {
样式表: 样式值;
...
}
使用语法, 在需要的位置利用 @extend
引用:
选择器 {
@extend %名字;
}
运算
借助于 sass:math
模块, sass
可以使用数学运算, 来处理一些颜色, 尺寸等计算.
借助循环等流程控制, 可以生成一些规则的类样式, 来提供一些特殊功能.
详细文档
详细文档主要包括
- 语法 (Syntax)
- 样式规则
- 变量
- 插值
- At 规则
- 值
- 运算
- 内置模块
- 突发变更
- 命令行
- 与 JS API 集成
语法 (Syntax)
概述
语法有两种, 一个 Scss
, 一个 Sass
Scss
与原有 CSS 类似, 使用花括号表示代码块, 层级.Sass
使用缩进来表示块, 其他几乎相同.
使用后缀名来进行区分: .scss
和 .sass
转换样式表 (略)
主要是介筛了代码文字使用的字符编码等. 统一使用 Unicode 字符集.
样式表结构 (了解)
与 CSS 类似, 几乎有样式声明来构成. 但 Sass 实际上可以看成 CSS 的扩展, 属于 CSS 的超集.
语句
Sass 的样式表由语句构成. 这些语句会被翻译成 CSS. 有些语句是一个块 (使用花括号定义), 块中可以包含其他语句.
在 SCSS 中语句使用分号结束, 除了语句块是例外. 在缩进语法中使用空行.
通用语句
可以使用在任何位置
- 变量声明
- 流程控制 (at-rule)
@error
,@warn
和@debug
CSS 语句
这些语句生成 CSS, 除了 函数中, 可以用在任何位置.
- 样式规则 (应该与 CSS 重合)
- CSS 的 at 语法. 例如
@media
,@font-face
等. @include
@at-root
顶级语句 (Top-Level)
这类语句只能使用在样式表, 或嵌套样式表的顶部位置.
- 模块加载,
@use
- 导入
@import
- 混入的定义
@mixin
- 函数定义
@function
其他语句
- 属性声明 (具体的样式属性与值). 使用在样式规则中, 或 CSS 的 at 规则中.
@extend
规则. 使用在样式规则中.
表达式
表达式就是一个右值. 可以放在右值位置的都是表达式.
任何 CSS 属性值都是 Sass 的表达式. 反之不一定.
Sass 的表达式非常强大, 将其称为 SassScript.
字面值
最简单的表达式
- 数字, 可以带有单位. 例如:
123
,123px
都是数字. - 字符串 (这个比较特殊): 可以包含引号, 也可以不含引号.
- 颜色. 可以是十六进数形式, 也可以是颜色名字.
- 布尔值.
true
和false
. - 单例的
null
. - 值列表 (也比较特殊). 使用空格, 或逗号分隔, 可能有方括号括起来, 也可能没有.
- 映射 (map). 使用 key 关联的数据, 结构与 JSON 一样.
// 值列表
$list: 1.5mm 1em 0 2em;
// 映射
$map: { "background": red, "foreground": pink };
运算
Sass 中内置了一些运算:
- 关系运算:
==
,!=
,>=
,>
,<
, 和<=
. - 算术运算:
+
,-
,*
,/
,%
. - 逻辑运算:
and
,or
, 和not
. +
,-
, 和/
可用于字符串连接. (注意, 这里的连接还是仅仅使用+
就够了)(
和)
可用于调整运算优先级.
其他表达式
- 变量
- 函数调用
- 特殊函数 (?)
- 父选择器
&
. !important
, 它会被转换成无引号字符串.
注释
- 行注释
//
- 块注释
/* ... */
- 不可删除注释
/*! ... */
- 三斜线的文档注释. 使用类似
JSDoc
的语法.
注意:
- 块注释中可以包含插值
#{ 表达式 }
. - 不可删除数值在 生成 CSS 并压缩后依旧保留.
特殊函数 (难点)
CSS 中有很多内置函数, 在 Scss 中会原样编译到 CSS 中 (解析为函数调用). 但有些例外. 这些特殊的函数无法简单的解析为 SassScript 表达式, 所有特殊函数都会返回 无引号字符串.
难点:
- CSS 内置函数有哪些? 这个有待深入一下.
- 无法转换的主要原因是什么?
url()
该函数是 CSS 中普遍使用的函数, 但其语法有别于其他函数, 它可以接收带有引号, 和不带引号的 URL. 由于无引号字符串在 SassScript 中不是表达式, 因此需要特殊处理.
- 如果
url()
参数是一个有效的无引号 URL, Sass 会原样解析它. 它还支持插值. - 如果不是, 它会被解析为一个普通的纯 CSS 函数调用.
例如:
$roboto-font-path: "../fonts/roboto";
url("#{$roboto-font-path}/Roboto-Thin.woff2")
// 会被解析为普通的函数调用, 它接收一个带引号的字符串
url("../fonts/roboto/Roboto-Thin.woff2")
url($roboto-font-path + "/Roboto-Light.woff2")
// 会被解析为普通的函数调用, 它接收一个运算表达式
url("../fonts/roboto/Roboto-Light.woff2")
url(#{$roboto-font-path}/Roboto-Regular.woff2)
// 会被转换为特殊函数, 它带有插值参数
url(../fonts/roboto/Roboto-Regular.woff2)
element(), progid:...(), 和 expression()
除了 element()
其他是历史遗留, 略.
element()
是 CSS 中定义的函数, 其作用是将 ID 转换为颜色.
$logo-element: logo-bg;
.logo {
background: element(##{$logo-element});
}
会转换为
.logo {
background: element(#logo-bg);
}
样式规则 (Style Rules)
样式规则在 Sass 与 CSS 中的作用是一样的, 用于给元素设置样式.
嵌套
选择器可以嵌套, 嵌套构成后代选择器结构 (不是子代).
如果嵌套的父级与子级都是选择器列表, 那么会将父子级别的选择器进行笛卡尔积处理, 来生成后代选择器.
在父级选择器后或子级选择器前, 可以添加组合选择器符号 (
+
,~
,>
) 来构成: 第一后继兄弟选择器, 后继兄弟选择器, 以及子代选择器.高级嵌套, 参考父选择器一节.
插值
选择器中可以支持插值, 借助于 @mixin
语法, 可以实现比较灵活的用法.
注意, 这表示选择器的名字中, 允许使用插值.
结合
@mixin
等语法不是必须的, 支持根据需要可以进行扩展.
$s1: "123";
.abc-#{$s1} {
color: red;
}
.abc-123 {
color: red;
}
提示: Sass 仅在插值解析完成后才会解析选择器. 也就是说可以适用插值来处理选择器的任何部分.
属性声明 (Property Declarations)
属性声明实际上就是样式样式属性, 用于设置元素的某一属性的样式如何显示.
就是例如,
background-color
,border
等.
Sass 中的属性声明扩展了 CSS, 更为强大. 其属性值可以是任意的 SassScript 表达式.
样式表 (块) 中可以有自己的变量.
$color: blue; .a { $color: red; color: $color; } .b { color: $color; }
.a { color: red; } .b { color: blue; }
插值
样式属性名中允许使用插值, 使用 #{ ... }
即可.
@mixin prefix($property, $value, $prefixes) {
@each $prefix in $prefixes {
-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}
.gray {
@include prefix(filter, grayscale(50%), moz webkit); // moz webkit 是无括号, 无逗号的列表
}
.gray {
-moz-filter: grayscale(50%);
-webkit-filter: grayscale(50%);
filter: grayscale(50%);
}
嵌套
选择器嵌套构成层级关系 (后代选择器).
属性名嵌套使用 -
连接.
.box {
border: {
color: red;
style: solid;
width: 1px;
}
}
.box {
border-color: red;
border-style: solid;
border-width: 1px;
}
注意语法, 选择器没有冒号. 属性有冒号.
针对短样式属性可以统一复制的, 嵌套中可以带上统一的取值.
$border: 1px solid blue;
.box {
border: $border {
color: red;
}
}
.box {
border: 1px solid blue;
border-color: red;
}
隐藏声明
可以控制在某写样式条件下, 某些样式属性存在或不存在
$rounded-corners: false;
.button {
border: 1px solid black;
border-radius: if($rounded-corners, 5px, null);
}
.button {
border: 1px solid black;
}
自定义属性
CSS 自定义属性, 常被称为 CSS 变量, 它有着特殊的定义语法. 在其声明值中可以使用大多数文本. 并且这些文本可与 js 进行交互. Sass 在转换自定义属性的时候, 除了插值, 会原样将其转换为 CSS.
简单来说就是要用变量的地方需要使用插值.
这部分细节再深入 CSS 变量后再二刷.
注意: 这里有一个问题, 插值会自动将字符串的引号去掉. 可以使用
meta
模块中的inspect
来保护引号:@use "sass:meta"; $font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; @warn ($font-family-sans-serif); @warn (#{$font-family-sans-serif}); @warn (#{meta.inspect($font-family-sans-serif)});