Sass 语言使用说明
Sass 是一种 CSS 预处理器语言,它的作者是 Hampton Catlin 和 Natalie Weizenbaum (nex3)。
2006 年,Ruby 正当红,Natalie 和 Hampton 基于 Ruby 实现了最初的 Sass 版本:Ruby Sass。该版本于 2019 年 3 月 26 日停止维护。
LibSass 是基于 C/C++ 实现的 Sass 库,目的是便于和其它编程语言整合。这个库也不再维护。
目前推荐使用的 Sass 基于 Dart 编程语言实现,即 Dart Sass,npm 上的 sass
包就是源自 Dart Sass
,只不过编译成了纯 JavaScript 代码。
目前最新的 Dart Sass
版本号是 1.80.6。
安装
把 Sass 安装为项目的开发依赖:
pnpm add --save-dev sass
Sass 支持两种语法风格,一种是 .sass
,使用缩进代表嵌套层级,另一种是 .scss
,更靠近原生的 CSS 语法,后者更常用。
如果希望把 .scss
文件编译为 .css
文件,执行如下命令:
pnpm sass input.scss output.css
如果希望实时监听文件或目录,使用 --watch
选项:
pnpm sass --watch input.scss output.css
如果监听的目标是文件夹,使用冒号 :
分隔源目录和目标目录:
pnpm sass --watch src/scss:dist/styles
变量
Sass 变量使用 $
前缀标识。
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
会被编译为:
body {
font: 100% Helvetica, sans-serif;
color: #333;
}
嵌套
源代码:
nav {
ul {
margin: 0;
padding: 0;
list-style:none;
}
li {
display: inline-block;
}
}
编译结果:
nav ul {
margin: 0;
padding: 0;
list-style:none;
}
nav li {
display: inline-block;
}
片段
片段文件以下划线 _
开头,比如 _partial.scss
。其中可以包含一些 CSS 代码片段,引入到其它模块中使用。
使用 @use
指令引入片段文件。
模块
2019 年 10 月 2 日发布的 Dart Sass 1.23.0 引入了模块系统的概念。在此之前的代码复用主要依靠 @import
指令,但是 @import
指令不好用,它会把全部成员引入到全局作用域,难以区分成员来源,无法避免命名冲突,因此不得不设计新的模块系统代替它。
利用模块,可以把不同的功能划分到不同文件,并使用 @use
指令引用。模块有自己的命名空间,因此可以方便区分来源,也能避免命名冲突。
源代码:
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
// input.scss
@use "base";
.inverse {
background-color: base.$primary-color;
color: white;
}
编译结果:
/* output.css */
body {
font: 100% Helvetica, sans-serif;
color: #333;
}
.inverse {
background-color: #333;
color: white;
}
注意,在上面的 @use "base";
中,无需后缀和下划线前缀,Sass 足够智能,会自动判断模块路径。
混入
如果需要多次使用一组相似的样式,可以把它们封装为混入(mixins)。混入可以包含参数,传入不同的具体值,实现样式的定制化。
定义混入使用 @mixin
指令,执行混入使用 @include
指令。
源代码:
@mixin theme($theme: DarkGray) { // <-- 定义混入
background: $theme;
box-shadow: 0 0 1px rgba($theme, 0.25);
color: #fff;
}
.info {
@include theme; // <-- 执行混入,使用默认值
}
.alert {
@include theme($theme: DarkRed); // <-- 执行混入,传入具体的值
}
.success {
@include theme($theme: DarkGreen);
}
编译结果:
.info {
background: DarkGray;
box-shadow: 0 0 1px rgba(169, 169, 169, 0.25);
color: #fff;
}
.alert {
background: DarkRed;
box-shadow: 0 0 1px rgba(139, 0, 0, 0.25);
color: #fff;
}
.success {
background: DarkGreen;
box-shadow: 0 0 1px rgba(0, 100, 0, 0.25);
color: #fff;
}
内容块
除了参数类型,混入还可以把整个样式块引入,使用 @content
指令表示样式的内容块。
源代码:
@mixin hover {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}
编译结果:
.button {
border: 1px solid black;
}
.button:not([disabled]):hover {
border-width: 2px;
}
扩展
使用 @extend
指令可以扩展(继承)其它选择器的属性。
和这个指令相关的另一个特性叫做占位符类(placeholder classes)。占位符类以 %
开头,只有当子类扩展它,它的代码才会出现在最终编译产物中。这有助于让编译结果保持精简和干净。
源代码:
// 下面的占位符类的代码会出现在编译结果中,因为有子类继承(扩展)它
%message-shared {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
// 下面的占位符类不会出现在编译结果,因为它没有子类
%equal-heights {
display: flex;
flex-wrap: wrap;
}
.message {
@extend %message-shared;
}
.success {
@extend %message-shared;
border-color: green;
}
.error {
@extend %message-shared;
border-color: red;
}
编译结果:
.error, .success, .message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
border-color: green;
}
.error {
border-color: red;
}
操作符
Sass 提供了标准的数学运算符号,比如 +
、-
、*
和 math.div()
,以及 %
。
@use "sass:math";
.container {
display: flex;
}
article[role="main"] {
width: math.div(600px, 960px) * 100%;
}
aside[role="complementary"] {
width: math.div(300px, 960px) * 100%;
margin-left: auto;
}
编译结果:
.container {
display: flex;
}
article[role=main] {
width: 62.5%;
}
aside[role=complementary] {
width: 31.25%;
margin-left: auto;
}
上面源代码中的 "sass:math"
是 Sass 内置的数学模块。
插值
插值几乎可以用在 Sass 样式表的任意地方,只要把变量使用 #{}
包裹即可。
源代码:
@mixin corner-icon($name, $top-or-bottom, $left-or-right) {
.icon-#{$name} {
background-image: url("/icons/#{$name}.svg");
position: absolute;
#{$top-or-bottom}: 0;
#{$left-or-right}: 0;
}
}
@include corner-icon("mail", top, left);
编译结果:
.icon-mail {
background-image: url("/icons/mail.svg");
position: absolute;
top: 0;
left: 0;
}
内置模块
Sass 的内置模块包括:
sass:math
处理数字计算sass:string
处理字符串sass:color
处理颜色sass:list
处理列表元素sass:map
处理哈希表sass:selector
处理选择器sass:meta
暴露 Sass 内部机制
sass:color
sass:color
模块包含大量处理颜色的使用函数。
比如 color.adjust($color, $red: null, $green: null, ...)
可以按照颜色通道、亮度、色相等参数调整颜色。
@use "sass:color";
@debug color.adjust(#6b717f, $red: 15); //=> #7a717f
@debug color.adjust(lab(40% 30 40), $lightness: 10%, $a: -20); //=> lab(50% 10 40)
@debug color.adjust(#d2e1dd, $hue: 45deg, $space: oklch); //=> rgb(209.7987810501, 223.8631944886, 229.398869806)