SCSS(SASS)
灵感胜于汗水 Lv5

SASS

Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。

  • 完全兼容 CSS3
  • 在 CSS 基础上增加变量、嵌套 (nesting)、混合 (mixins) 等功能
  • 通过函数进行颜色值与属性值的运算
  • 提供控制指令 (control directives)等高级功能
  • 自定义输出格式

嵌套规则

Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,例如:

1
2
3
4
5
6
7
8
9
#main p {
color: #00ff00;
width: 97%;

.redbox {
background-color: #ff0000;
color: #000000;
}
}

嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理。

父选择器 &

在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,或者当 body 元素有某个 classname 时,可以用 & 代表嵌套规则外层的父选择器。

1
2
3
4
5
6
a {
font-weight: bold;
text-decoration: none;
&:hover { text-decoration: underline; }
body.firefox & { font-weight: normal; }
}

编译后的 CSS 文件中 & 将被替换成嵌套外层的父选择器,如果含有多层嵌套,最外层的父选择器会一层一层向下传递。

& 必须作为选择器的第一个字符,其后可以跟随后缀生成复合的选择器。

属性嵌套

有些 CSS 属性遵循相同的命名空间 (namespace),比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中,例如:

1
2
3
4
5
6
7
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}

命名空间也可以包含自己的属性值,例如:

1
2
3
4
5
6
.funky {
font: 20px/24px {
family: fantasy;
weight: bold;
}
}

编译为

1
2
3
4
5
.funky {
font: 20px/24px;
font-family: fantasy;
font-weight: bold;
}

注释

Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 //,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会。

插值语句 (interpolation) 也可写进多行注释中输出变量值:

1
2
$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */

编译为

1
/* This CSS is generated by My Snazzy Framework version 1.2.3. */

变量

变量以美元符号开头,赋值方法与 CSS 属性的写法一样:

1
$width: 5em;

直接使用即调用变量:

1
2
3
#main {
width: $width;
}

变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 !global 声明:

1
2
3
4
5
6
7
8
#main {
$width: 5em !global;
width: $width;
}

#sidebar {
width: $width;
}

插值语句 #{}

通过 #{} 插值语句可以在选择器或属性名中使用变量:

1
2
3
4
5
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}

编译为

1
2
p.foo {
border-color: blue; }

运算

所有数据类型均支持相等运算 ==!=,此外,每种数据类型也有其各自支持的运算方式。

数字运算

支持数字的加减乘除、取整等运算 (+, -, *, /, %),如果必要会在不同单位间转换值。

1
2
3
p {
width: 1in + 8pt;
}

编译为

1
2
3
p {
width: 1.111in;
}

关系运算 <, >, <=, >= 也可用于数字运算,相等运算 ==, != 可用于所有数据类型。

圆括号可以用来影响运算的顺序:

1
2
3
p {
width: 1em + (2em * 3);
}

编译为

1
2
p {
width: 7em; }

除法运算

/ 在 CSS 中通常起到分隔数字的用途,SassScript 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了 / 除法运算的功能。也就是说,如果 / 在 SassScript 中把两个数字分隔,编译后的 CSS 文件中也是同样的作用。

以下三种情况 / 将被视为除法运算符号:

  • 如果值,或值的一部分,是变量或者函数的返回值
  • 如果值被圆括号包裹
  • 如果值是算数表达式的一部分
1
2
3
4
5
6
7
8
p {
font: 10px/8px; // 普通CSS
$width: 1000px;
width: $width/2; // 使用变量,做除法
width: round(1.5)/2; // 使用函数,做除法
height: (500px/2); // 使用括号,做除法
margin-left: 5px + 8px/2px; // 使用 + ,做除法
}

编译为

1
2
3
4
5
6
p {
font: 10px/8px;
width: 500px;
height: 250px;
margin-left: 9px;
}

如果需要使用变量,同时又要确保 / 不做除法运算而是完整地编译到 CSS 文件中,只需要用 #{} 插值语句将变量包裹:

1
2
3
4
5
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}

编译为

1
2
3
p {
font: 12px/30px;
}

颜色值运算

颜色值的运算是分段计算进行的,也就是分别计算红色,绿色,以及蓝色的值:

1
2
3
p {
color: #010203 + #040506;
}

计算 01 + 04 = 05 02 + 05 = 07 03 + 06 = 09,然后编译为

1
2
p {
color: #050709; }

数字与颜色值之间也可以进行算数运算,同样也是分段计算的,比如

1
2
3
p {
color: #010203 * 2;
}

计算 01 * 2 = 02 02 * 2 = 04 03 * 2 = 06,然后编译为

1
2
p {
color: #020406; }

布尔运算

支持布尔型的 and or 以及 not 运算。

@import

Sass 拓展了 @import 的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。

如果需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要编译这些文件,但导入语句中却不需要添加下划线。

例如,将文件命名为 _colors.scss,便不会编译 _colours.css 文件。

1
@import "colors";

上面的例子,导入的其实是 _colors.scss 文件。

注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。

嵌套 @import

大多数情况下,一般在文件的最外层(不在嵌套规则内)使用 @import,其实,也可以将 @import 嵌套进 CSS 样式或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中。

假设 example.scss 文件包含以下样式:

1
2
3
.example {
color: red;
}

然后导入到 #main 样式内

1
2
3
#main {
@import "example";
}

将会被编译为

1
2
3
#main .example {
color: red;
}

不可以在混合指令 (mixin) 或控制指令 (control directives) 中嵌套 @import

@extend

告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。

1
2
3
4
5
6
7
8
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}

@extend 的作用是将重复使用的样式 (.error) 延伸 (extend) 给需要包含这个样式的特殊样式(.seriousError

!optional 声明

如果 @extend 失败会收到错误提示,比如,这样写 a.important {@extend .notice},当没有 .notice 选择器时,将会报错,只有 h1.notice 包含 .notice 时也会报错,因为 h1a 冲突,会生成新的选择器。

如果要求 @extend 不生成新选择器,可以通过 !optional 声明达到这个目的,例如:

1
2
3
a.important {
@extend .notice !optional;
}

混合指令

混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。

@mixin

混合指令的用法是在 @mixin 后添加名称与样式,比如名为 large-text 的混合通过下面的代码定义:

1
2
3
4
5
6
7
8
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}

@include

使用 @include 指令引用混合样式,格式是在其后添加混合名称,以及需要的参数(可选):

1
2
3
4
5
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}

编译为

1
2
3
4
5
6
7
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px; }

也可以在最外层引用混合样式,不会直接定义属性,也不可以使用父选择器。

1
2
3
4
5
6
7
@mixin silly-links {
a {
color: blue;
background-color: red;
}
}
@include silly-links;

编译为

1
2
3
a {
color: blue;
background-color: red; }

混合样式中也可以包含其他混合样式。

混合样式中应该只定义后代选择器,这样可以安全的导入到文件的任何位置。

参数

参数用于给混合指令中的样式设定变量,并且赋值使用。在定义混合指令的时候,按照变量的格式,通过逗号分隔,将参数写进圆括号里。引用指令时,按照参数的顺序,再将所赋的值对应写进括号:

1
2
3
4
5
6
7
8
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue, 1in); }

编译为

1
2
3
4
p {
border-color: blue;
border-width: 1in;
border-style: dashed; }

混合指令也可以使用给变量赋值的方法给参数设定默认值,然后,当这个指令被引用的时候,如果没有给参数赋值,则自动使用默认值:

1
2
3
4
5
6
7
8
9
@mixin sexy-border($color, $width: 1in) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue); }
h1 { @include sexy-border(blue, 2in); }

混合指令也可以使用关键词参数,上面的例子也可以写成:

1
2
p { @include sexy-border($color: blue); }
h1 { @include sexy-border($color: blue, $width: 2in); }

虽然不够简明,但是阅读起来会更方便。

函数指令

Sass 支持自定义函数,并能在任何属性值或 Sass script 中使用:

1
2
3
4
5
6
7
8
$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); }

编译为

1
2
#sidebar {
width: 240px; }

与 mixin 相同,也可以传递若干个全局变量给函数作为参数。一个函数可以含有多条语句,需要调用 @return 输出结果。

自定义的函数也可以使用关键词参数,上面的例子还可以这样写:

1
#sidebar { width: grid-width($n: 5); }

建议在自定义函数前添加前缀避免命名冲突,其他人阅读代码时也会知道这不是 Sass 或者 CSS 的自带功能。

  • 本文标题:SCSS(SASS)
  • 本文作者:灵感胜于汗水
  • 创建时间:2022-11-02 19:07:10
  • 本文链接:https://cjhsyc.github.io/2022/11/02/SCSS-SASS/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!