Sass 基础
01. 环境安装
安装与使用基本上是配合 node
构建工具一起使用. 并未直接用 Dart
或 Ruby
等版本.
例如与 Vue-CLI
等脚手架工具一起集成.
使用配置推荐:
使用 VSCode 插件 (推荐)
- 使用 VSCode 插件 Live Sass Compiler, 在保存时直将 sass 文件转换为 css 文件.
- 使用时需要点击 VSCode 下方的 Watch Sass 开启.
使用 sass 命令行程序
$ npm i -g sass
可以使用的命令很多: node-sass 也可以
PS C:\Users\jiangkun> sass -h
Compile Sass to CSS.
Usage: sass <input.scss> [output.css]
sass <input.scss>:<output.css> <input/>:<output/> <dir/>
=== Input and Output ===================
--[no-]stdin Read the stylesheet from stdin.
--[no-]indented Use the indented syntax for input from stdin.
-I, --load-path=<PATH> A path to use when resolving imports.
May be passed multiple times.
-s, --style=<NAME> Output style.
[expanded (default), compressed]
--[no-]charset Emit a @charset or BOM for CSS with non-ASCII characters.
(defaults to on)
--[no-]error-css When an error occurs, emit a stylesheet describing it.
Defaults to true when compiling to a file.
--update Only compile out-of-date stylesheets.
=== Source Maps ========================
--[no-]source-map Whether to generate source maps.
(defaults to on)
--source-map-urls How to link from source maps to source files.
[relative (default), absolute]
--[no-]embed-sources Embed source file contents in source maps.
--[no-]embed-source-map Embed source map contents in CSS.
=== Other ==============================
-w, --watch Watch stylesheets and recompile when they change.
--[no-]poll Manually check for changes rather than using a native watcher.
Only valid with --watch.
--[no-]stop-on-error Don't compile more files once an error is encountered.
-i, --interactive Run an interactive SassScript shell.
-c, --[no-]color Whether to use terminal colors for messages.
--[no-]unicode Whether to use Unicode characters for messages.
-q, --[no-]quiet Don't print warnings.
--[no-]quiet-deps Don't print compiler warnings from dependencies.
Stylesheets imported through load paths count as dependencies.
--[no-]verbose Print all deprecation warnings even when they're repetitive.
--[no-]trace Print full Dart stack traces for exceptions.
-h, --help Print this usage information.
--version Print the version of Dart Sass.
PS C:\Users\jiangkun> node-sass --help
Wrapper around libsass
Usage:
node-sass [options] <input.scss>
cat <input.scss> | node-sass [options] > output.css
Example: Compile foobar.scss to foobar.css
node-sass --output-style compressed foobar.scss > foobar.css
cat foobar.scss | node-sass --output-style compressed > foobar.css
Example: Watch the sass directory for changes, compile with sourcemaps to the css directory
node-sass --watch --recursive --output css
--source-map true --source-map-contents sass
Options
-w, --watch Watch a directory or file
-r, --recursive Recursively watch directories or files
-o, --output Output directory
-x, --omit-source-map-url Omit source map URL comment from output
-i, --indented-syntax Treat data from stdin as sass code (versus scss)
-q, --quiet Suppress log output except on error
-v, --version Prints version info
--output-style CSS output style (nested | expanded | compact | compressed)
--indent-type Indent type for output CSS (space | tab)
--indent-width Indent width; number of spaces or tabs (maximum value: 10)
--linefeed Linefeed style (cr | crlf | lf | lfcr)
--source-comments Include debug info in output
--source-map Emit source map (boolean, or path to output .map file)
--source-map-contents Embed include contents in map
--source-map-embed Embed sourceMappingUrl as data URI
--source-map-root Base path, will be emitted in source-map as is
--include-path Path to look for imported files
--follow Follow symlinked directories
--precision The amount of precision allowed in decimal numbers
--error-bell Output a bell character on errors
--importer Path to .js file containing custom importer
--functions Path to .js file containing custom functions
--help Print usage info
02. 语法 [官网阅读笔记]
https://sass-lang.com/
Sass 有两种语法, 一个是 SCSS 类似 CSS 的语法, 另一个是 SASS, 是缩进语法.
1. 样式表转换 [无痛痒]
Sass 使用文本文件编码, 转换是直接进行的, 不会出现中间令牌流转换.
2. 样式表结构
与 CSS 类似, Sass 由包含属性声明的样式规则组成. 但 Sass 会更强大.
声明 [无痛痒]
Sass 由一些列的声明构成. 这些声明会被转换为 CSS.
有些声明包含块, 即 {
和 }
. 其中包含其他声明.
例如, 一条样式规则就是一个 声明 + 块, 块中一般含有属性声明.
在 Scss 中, 声明与声明之间由分号分隔.
- 通用声明. 这类声明可以用在任何地方. 如: 变量声明, 流程控制,
@error
,@warn
, 或@debug
等. - CSS 声明. 这类声明会生成 CSS, 除了
@function
中可以用在任何位置.- 例如样式规则, CSS 规则, 混入,
@at-root
等
- 例如样式规则, CSS 规则, 混入,
- 顶级声明. 这类声明只能用在样式表的顶层, 或嵌套在 CSS 声明的顶层.
- 例如模块加载
@use
, 导入@import
, 混入定义@mixin
, 或函数定义@function
- 例如模块加载
- 其他声明.
- 例如属性声明,
@extend
等.
- 例如属性声明,
表达式 [熟悉]
表达式是放在属性或变量声明右边的内容. 每一个表达式都得到一个值.
任何有效的 CSS 属性值都是合法的 Sass 表达式. 但是 Sass 表达式更为强大.
可以作为参数传入函数, 可以计算, 可以处理流程控制等.
- 字面量 literal
- 数字, 可以有单位或没有单位
- 字符串, 可能有引号, 或没有引号
- 颜色, 十六进制颜色, 或命名颜色
- 布尔值,
true
或false
- 单一的
null
- 列表值, 注意可以由 空格, 逗号分割, 可以有方括号括起来, 也可以没有.
font
属性值就是个典型的列表. - 映射 (map). 形如:
("background": red, "foreground": pink)
- 运算 operation
- 判等
==
或!=
- 算术运算
+
,-
,*
,/
, 和%
. 可以带有单位, 但是必须单位一致. - 关系运算
>
,>=
,<
,<=
, 用于比较大小. - 逻辑运算符
and
,or
, 和not
运算符. Sass 中false
和null
为false
, 其他视为true
. +
,-
, 和/
可以用于连接字符串.-
和/
就是形式上的连接, 可以用在特殊的位置.
- 圆括号可以用于提升优先级.
- 判等
- 其他表达式
- 变量, 例如
$var
- 函数调用, 例如
nth($list, 1)
或var(--margin-bg-color)
.- 可以调用 Sass 内置函数, 用户自定义函数, 会直接编译为 CSS
- CSS 函数, CSS 函数会直接编译到 CSS 文件中.
- 特殊函数. 例如:
calc(1px + 100%)
或url(http://...)
它们具有特定的转换规则. - 父级选择器,
&
- 值
!important
会转换为无引号字符串.
- 变量, 例如
3. 注释 [重要]
注释与 JS 注释逻辑类似.
- 行注释
//
, 尽在 Sass 中有效, 编译成 CSS 后会被移除. - 块注释
/* ... */
, 也叫多行注释, 该注释会在编译成 CSS 后保留.- 在块注释中允许含有插值表达式. 例如
#{ 1 + 2 }
- 在块注释中允许含有插值表达式. 例如
- 保护块注释
/*! ... */
. 若使用压缩模式生成 CSS, 那么所有注释都会被移除, 除非使用保护块注释.
块注释可以用在允许空格的任意位置.
4. 特殊函数 [重要]
CSS 中有一些函数, 大部分在 Sass 中可以很好的使用, 最终编译成 CSS 时原样输出, 但有些不行.
主要原因在于引号的问题. 所有的特殊函数调用, 均被编译为 无引号字符串.
url()
url()
函数在 CSS 中使用频繁, 但是其语法与其他函数有一点区别:
该函数可以使用带有引号或无引号的 URL 作为参数, 但是无引号的 URL 不是合法的 Sass 表达式, 因此需要转换.
- 如果参数是合法的无引号 Url, 那么 Sass 将其原封不动的转换为 CSS. 其中允许使用插值.
- 如果不是合法的无引号 Url, 例如, 含有变量或函数调用, 它被转换为普通的纯 CSS 函数调用.
没完全明白其用法
element()
, progid:...()
, 和 expression()
element()
的参数使用 ID 选择器时, 由于 #
可以解释为颜色, 故需要插值形式来写:
element(##{插值表达式})
其他赞略.
03. 样式规则
样式规则是 Sass 的基础, 就好比它对于 CSS 一样. 它采用相同的工作方式: 你使用选择器来选择元素设置样式, 使用属性声明来设置元素的外观.
概览
1. 嵌套
Sass 减少了一次次重复书写选择器, 可以使用嵌套来描述层级关系. 编译器会自动展开连接外层与内层选择器.
用法习惯, 尽可能不要嵌套太深, 会影响性能.
2. 选择器列表
嵌套的选择器列表会进行排列组合.
.s1, .s2 {
.ss1, .ss2 {
/* ... */
}
}
会转换为
.s1 .ss1, .s1 .ss2, .s2 .ss1, .s2 .ss2 {
/* ... */
}
3. 选择器组合
在处理组合选择器时, 连接选择器的符号, 例如 >
, +
, ~
等, 可以放在外层选择器结尾处, 或内层选择器开头位置. 甚至单独放一层括号.
Sass 只是简单的将其连接在一起.
高级嵌套. 参考 父选择器.
4. 插值
可以在选择器名字, 属性名字等上使用插值, 在使用一个模式生成多个选择器样式非常有用.
1. 属性声明
属性声明在 CSS 和 Sass 中的成分一样.
不同的是 Sass 中可以使用表达式. 比起 CSS 书写更容易.
插值
属性名中可以包含插值, 可以动态生成需要的属性. bootstrap 中的栅格数字都是采用这个方式生成的.
嵌套
对于公有的前缀的样式属性, 可以使用属性名的嵌套. 注意语法上与选择器嵌套的区别.
.box {
border: {
width: 1px;
color: red;
}
}
会生成
.box {
border-width: 1px;
border-color: red;
}
有些样式属性有长版本和端版本, 允许同时对其赋值.
.info-page {
margin: auto {
bottom: 10px;
top: 2px;
}
}
生成
.info-page {
margin: auto;
margin-bottom: 10px;
margin-top: 2px;
}
隐藏声明
在属性值为 null
或 空的无引号
字符串时, 编译器不会对其编译. 可以用于动态生成样式.
这时可以使用 if()
函数, 逻辑上就是三目运算符.
if (表达式, 为真取值, 为假取值)
自定义属性 [暂略, 待深入]
自定义属性即为 CSS 变量.
待深入 CSS 变量的内容
https://sass-lang.com/documentation/style-rules/declarations#custom-properties
2. 父选择器
父选择器 &
是一个特殊的选择器, 用于表示父级选择器名字, 使用它可以用于构造复杂的选择器.
父选择器位置并未严格定义. 可以是任意的.
.alert {
&:hover { /* ... */ }
[dir=rt] & { /* ... */ }
:not(&) { /* ... */ }
}
作为前缀
.parent {
&__mark1 { /* ... */ }
}
会得到
.parent__mark1 { /* ... */ }
使用父选择器后, 展开嵌套后, 就直接跃进一层级.
嵌入 SassScript 中 [待深入]
在 Sass 脚本中, 可以使用 &
引用父选择器.
高级嵌套 [待深入]
技巧性较强, 可反复实验: https://sass-lang.com/documentation/style-rules/parent-selector
3. 占位选择器
Sass 有一类特殊的选择器被称为占位选择器. 它看起来与行为都类似于 CSS 选择器.
不同的是它用 %
开头, 并且不会编译到 CSS 中.
- 它类似于一个模板, 定义一个样式表. 在无选择器使用 (
@extend
) 的时候, 不会编译到 CSS 中. - 若有选择器使用, 只需要在选择器中使用
@extend %占位选择器;
即可激活该样式表.
在使用 Sass 编写样式表模板的时候, 这个占位选择器很好用. 是的 CSS 会更加简洁.
04. 变量
使用 $
开头声明变量, 使用 :
赋值. 一个变量看起来就像一个属性声明.
CSS 也有变量, 与 Sass 变量不同
- Sass 变量会全部编译掉. 转换的 CSS 文件中不会有 Sass 变量. 而 CSS 的变量只会包含在 CSS 文件中.
- CSS 变量在不同元素中可以有不同值, 但是在 Sass 中, 一个时刻只允许有一个值.
- Sass 变量是命令式的. 改变变量的值, 对先前的使用不影响. 而 CSS 变量是声明式的, 一改全改.
由于历史原因, 在 Sass 变量中不区分中划线与下划线.
1. 默认值
在模块中定义的变量可以有默认值, 从外部引用时可以修改默认值.
定义变量时, 使用
!default
作为结尾.引用模块时, 若要修改变量默认值, 可以使用:
@use <url> with( <variable>: <value>, <variable>: <value> )
2. 内置变量
内置变量的值无法修改
3. 作用域
变量是顶级作用域的. 在当前选择器中定义就可以在当前选择器中使用.
逻辑上可以将选择器看成函数, 那么逻辑与
js
中var
变量就很像了.
隐藏变量
逻辑与 C#
中派生类 new
成员一样, 选择器中与全局有同名的变量, 选择器中局部变量覆盖全局变量作用域.
要在局部作用域 (选择器中) 修改全局变量, 只需要在结尾处加上 !global
. 逻辑与 PHP
类似.
注意:
!global
不可用于新变量, 必须该变量已定义过.
在流程控制中
在流程控制中的变量不是新定义变量. 不会存在隐藏变量的情况.
4. 高级变量函数 [待深入]
Sass Core 中提供了几个用于操作变量的函数.
待深入 https://sass-lang.com/documentation/variables#advanced-variable-functions
05. 插值 [待深入]
插值可以用在很多地方.
- 样式规则选择器中
- 声明的属性名中
- 自定义属性值中
- CSS 的 at 规则中
- @extends
- 纯 CSS @imports 中
- 带引号或无引号字符串中
- 特殊函数中
- 纯 CSS 函数名中
- 注释中
有几个点待深入
https://sass-lang.com/documentation/interpolation