Scss语法二@Rules和指令

续接上回。

@-Rules和指令

Sass 支持所有的 CSS3 @-Rules,以及 Sass 特有的 “指令”(directives)

@import

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

导入文件也可以使用 #{ } 插值语句,但不是通过变量动态导入 Sass 文件,只能作用于 CSS 的 url() 导入方式:

1
2
$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=\#{$family}");
嵌套@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

@media

Sass 中 @media 指令与 CSS 中用法一样,只是增加了一点额外的功能:允许其在 CSS 规则中嵌套。如果 @media 嵌套在 CSS 规则内,编译时,@media 将被编译到文件的最外层,包含嵌套的父选择器。这个功能让 @media 用起来更方便,不需要重复使用选择器,也不会打乱 CSS 的书写流程。

1
2
3
4
5
6
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}

编译为

1
2
3
4
5
6
7
.sidebar {
width: 300px; }
@media screen and (orientation: landscape) {
.sidebar {
width: 500px;
}
}
@extend

在设计网页的时候常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在 HTML 中给元素定义两个 class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:

1
2
3
<div class="error seriousError">
Oh no! You've been hacked!
</div>

样式如下

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

麻烦的是,这样做必须时刻记住使用 .seriousError 时需要参考 .error 的样式,带来了很多不变:智能比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。使用 @extend 可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。

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

上面代码的意思是将 .error 下的所有样式继承给 .seriousErrorborder-width: 3px; 是单独给 .seriousError 设定特殊样式,这样,使用 .seriousError 的地方可以不再使用 .error

当一个选择器延伸给第二个后,可以继续将第二个选择器延伸给第三个,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
.criticalError {
@extend .seriousError;
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}

现在,每个 .seriousError 选择器将包含 .error 的样式,而 .criticalError 不仅包含 .seriousError 的样式也会同时包含 .error 的所有样式,上面的代码编译为:

1
2
3
4
5
6
7
8
9
10
11
12
13
.error, .seriousError, .criticalError {
border: 1px #f00;
background-color: #fdd; }

.seriousError, .criticalError {
border-width: 3px; }

.criticalError {
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%; }
@extend-Only选择器

配合占位符选择器使用,前边已做标记。可以翻看占位符选择器部分。

@at-root

@at-root指令可以使一个或多个规则被限定输出在文档的根层级上,而不是被嵌套在其父选择器下。

下面就通过scss代码实例介绍一下它的作用:

  没有使用@at-root命令的默认情况。

1
2
3
4
5
6
7
.parent{
color:red;
.child {
width:200px;
height:50px;
}
}

  编译成css代码如下:

1
2
3
4
5
6
7
.parent {
color: red;
}
.parent .child {
width: 200px;
height: 50px;
}

  使用@at-root命令的scss代码

1
2
3
4
5
6
7
.parent{
color:red;
@at-root .child {
width:200px;
height:50px;
}
}

  编译后的css代码如下:

1
2
3
4
5
6
7
.parent {
color: red;
}
.child {
width: 200px;
height: 50px;
}

由于使用@at-root命令,那么.child就不参与嵌套,直接跳出嵌套。

在默认情况下,@at-root只会跳出选择器嵌套,而不会跳出指令

scss实例如下:

1
2
3
4
5
6
7
8
@media print { 
@at-root{
.foo {
color: green;
color: gray;
}
}
}

  编译后的css代码如下:

1
2
3
4
5
6
@media print {
.foo {
color: green;
color: gray;
}
}

默认 @at-root 只会跳出选择器嵌套,而不能跳出 @media 或 @support,如果要跳出这两种,则需使用 @at-root(without: media),@at-root(without: support)。这个语法的关键词有四个:all(表示所有), rule(表示常规), media(表示 media),support(表示 support )。我们默认的 @at-root 其实就是 @at-root( without: rule )。如果指定的不是all,则只会跳出指定的嵌套,可以指定多个如@at-root(without: media rule)

控制指令

SassScript 提供了一些基础的控制指令,比如在满足一定条件时引用样式,或者设定范围重复输出格式。控制指令是一种高级功能,日常编写过程中并不常用到,主要与混合指令 (mixin) 配合使用,尤其是用在 Compass 等样式库中。

@if

@if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:

1
2
3
4
5
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}

编译为

1
2
p {
border: 1px solid; }

@if 声明后面可以跟多个 @else if 声明,或者一个 @else 声明。如果 @if 声明失败,Sass 将逐条执行 @else if 声明,如果全部失败,最后执行 @else 声明,例如:

1
2
3
4
5
6
7
8
9
10
11
12
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}

编译为

1
2
3
p {
color: green;
}
@for

@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。这个指令包含两种格式:@for $var from <start> through <end>,或者 @for $var from <start> to <end>,区别在于 throughto 的含义:当使用 through 时,条件范围包含 <start><end> 的值,而使用 to 时条件范围只包含 <start> 的值不包含 <end> 的值。另外,$var 可以是任何变量,比如 $i<start><end> 必须是整数值。

1
2
3
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}

编译为

1
2
3
4
5
6
.item-1 {
width: 2em; }
.item-2 {
width: 4em; }
.item-3 {
width: 6em; }
@while

@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
.item-6 {
width: 12em; }

.item-4 {
width: 8em; }

.item-2 {
width: 4em; }
作者

胡兆磊

发布于

2022-06-30

更新于

2022-10-23

许可协议