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

    Sass 在当前地址,或 Rack, Rails, Merb 的 Sass 文件地址寻找 Sass 文件,如果需要设定其他地址,可以用 :load_paths 选项,或者在命令行中输入 —load-path 命令。

    通常, 寻找 Sass 文件并将其导入,但在以下情况下,@import 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。

    • 文件拓展名是 .css
    • 文件名以 http:// 开头;
    • 文件名是 url()
    • 包含 media queries。 如果不在上述情况内,文件的拓展名是 .scss.sass,则导入成功。没有指定拓展名,Sass 将会试着寻找文件名相同,拓展名为 .scss.sass 的文件并将其导入。

    1. @import "foo";

    都会导入文件 foo.scss,但是

    1. @import "foo.css";
    2. @import "foo" screen;
    3. @import "http://foo.com/bar";
    4. @import url(foo);

    编译为

    1. @import "foo.css";
    2. @import "foo" screen;
    3. @import "http://foo.com/bar";
    4. @import url(foo);

    Sass 允许同时导入多个文件,例如同时导入 rounded-corners 与 text-shadow 两个文件:

    1. @import "rounded-corners", "text-shadow";

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

    1. $family: unquote("Droid+Sans");
    2. @import url("http://fonts.googleapis.com/css?family=\#{$family}");

    编译为

    1. @import url("http://fonts.googleapis.com/css?family=Droid+Sans");

    7.1.1. 分音 (Partials)

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

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

    1. @import "colors";

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

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

    7.1.2. 嵌套 @import

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

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

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

    然后导入到 #main 样式内

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

    将会被编译为

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

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

    7.2.

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

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

    编译为

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

    @media 的 queries 允许互相嵌套使用,编译时,Sass 自动添加 and

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

    编译为

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

    甚至可以使用 SassScript(比如变量,函数,以及运算符)代替条件的名称或者值:

    1. $media: screen;
    2. $feature: -webkit-min-device-pixel-ratio;
    3. $value: 1.5;
    4. @media #{$media} and ($feature: $value) {
    5. .sidebar {
    6. width: 500px;
    7. }
    8. }

    编译为

    1. @media screen and (-webkit-min-device-pixel-ratio: 1.5) {
    2. .sidebar {
    3. width: 500px; } }
    1. <div class="error seriousError">
    2. Oh no! You've been hacked!
    3. </div>

    样式如下

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

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

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

    其他使用到 .error 的样式也会同样继承给 .seriousError,例如,另一个样式 .error.intrusion 使用了 hacked.png 做背景,<div class="seriousError intrusion"> 也同样会使用 hacked.png 背景。

    1. .error.intrusion {
    2. background-image: url("/image/hacked.png");
    3. }

    7.3.1. How it Works

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

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .error.intrusion {
    6. background-image: url("/image/hacked.png");
    7. }
    8. .seriousError {
    9. }

    编译为

    1. .error, .seriousError {
    2. border: 1px #f00;
    3. background-color: #fdd; }
    4. .error.intrusion, .seriousError.intrusion {
    5. background-image: url("/image/hacked.png"); }
    6. .seriousError {
    7. border-width: 3px; }

    当合并选择器时,@extend 会很聪明地避免无谓的重复,.seriousError.seriousError 将编译为 .seriousError,不能匹配任何元素的选择器(比如 #main#footer )也会删除。

    7.3.2. 延伸复杂的选择器 (Extending Complex Selectors)

    Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.coola:hover 或者 a.user[href^=";] 等,例如:

    1. .hoverlink {
    2. @extend a:hover;
    3. }

    同 class 元素一样,a:hover 的样式将继承给 .hoverlink

    1. .hoverlink {
    2. @extend a:hover;
    3. }
    4. a:hover {
    5. text-decoration: underline;
    6. }

    编译为

    1. a:hover, .hoverlink {
    2. text-decoration: underline; }

    与上面 .error.intrusion 的例子一样,所有 a:hover 的样式将继承给 .hoverlink,包括其他使用到 a:hover 的样式,例如:

    1. .hoverlink {
    2. @extend a:hover;
    3. }
    4. .comment a.user:hover {
    5. font-weight: bold;
    6. }

    编译为

    1. .comment a.user:hover, .comment .user.hoverlink {
    2. font-weight: bold; }

    7.3.3. 多重延伸 (Multiple Extends)

    同一个选择器可以延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器:

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .attention {
    6. font-size: 3em;
    7. background-color: #ff0;
    8. }
    9. .seriousError {
    10. @extend .error;
    11. @extend .attention;
    12. border-width: 3px;
    13. }

    编译为

    1. .error, .seriousError {
    2. border: 1px #f00;
    3. background-color: #fdd; }
    4. .attention, .seriousError {
    5. font-size: 3em;
    6. background-color: #ff0; }
    7. .seriousError {
    8. border-width: 3px; }

    每个 .seriousError 将包含 .error.attention 下的所有样式,这时,后定义的样式享有优先权:.seriousError 的背景颜色是 #ff0 而不是 #fdd,因为 .attention.error 之后定义。

    多重延伸可以使用逗号分隔选择器名,比如 @extend .error, .attention; .error; @extend.attention 有相同的效果。

    7.3.4. 继续延伸 (Chaining Extends)

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

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

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

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

    7.3.5. 选择器列 (Selector Sequences)

    暂时不可以将选择器列 (Selector Sequences),比如 .foo .bar.foo + .bar,延伸给其他元素,但是,却可以将其他元素延伸给选择器列:

    1. #fake-links .link {
    2. @extend a;
    3. }
    4. a {
    5. color: blue;
    6. &:hover {
    7. text-decoration: underline;
    8. }
    9. }

    编译为

    1. a, #fake-links .link {
    2. color: blue; }
    3. a:hover, #fake-links .link:hover {
    4. text-decoration: underline; }
    7.3.5.1. 合并选择器列 (Merging Selector Sequences)

    有时会遇到复杂的情况,比如选择器列中的某个元素需要延伸给另一个选择器列,这种情况下,两个选择器列需要合并,比如:

    1. font-weight: bold;
    2. }
    3. #demo .overview .fakelink {
    4. @extend a;

    技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,上面这个简单的例子就可能有 10 种结果。所以,Sass 只会编译输出有用的选择器。

    当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前:

    1. #admin .tabbar a {
    2. font-weight: bold;
    3. }
    4. #demo .overview .fakelink {
    5. @extend a;
    6. }

    编译为

    1. #admin .tabbar a {
    2. font-weight: bold;
    3. }
    4. #admin .overview .fakelink {
    5. @extend a;
    6. }

    编译为

    1. #admin .tabbar a,
    2. #admin .tabbar .overview .fakelink,
    3. #admin .overview .tabbar .fakelink {
    4. font-weight: bold; }

    7.3.6. -Only 选择器 (@extend-Only Selectors)

    有时,需要定义一套样式并不是给某个元素用,而是只通过 指令使用,尤其是在制作 Sass 样式库的时候,希望 Sass 能够忽略用不到的样式。

    如果使用普通的 CSS 规则,最后会编译出很多用不到的样式,也容易与其他样式名冲突,所以,Sass 引入了“占位符选择器” (placeholder selectors),看起来很像普通的 idclass 选择器,只是 #. 被替换成了 %。可以像 class 或者 id 选择器那样使用,当它们单独使用时,不会被编译到 CSS 文件中。

    1. // This ruleset won't be rendered on its own.
    2. #context a%extreme {
    3. color: blue;
    4. font-weight: bold;
    5. font-size: 2em;
    6. }

    占位符选择器需要通过延伸指令使用,用法与 class 或者 id 选择器一样,被延伸后,占位符选择器本身不会被编译。

    1. .notice {
    2. @extend %extreme;
    3. }

    编译为

    1. #context a.notice {
    2. color: blue;
    3. font-weight: bold;
    4. font-size: 2em; }

    7.3.7. !optional 声明 (The !optional Flag)

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

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

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

    7.3.8. 在指令中延伸 ( in Directives)

    在指令中使用 @extend 时(比如在 中)有一些限制:Sass 不可以将 @media 层外的 CSS 规则延伸给指令层内的 CSS,这样会生成大量的无用代码。也就是说,如果在 (或者其他 CSS 指令)中使用 @extend,必须延伸给相同指令层中的选择器。

    下面的例子是可行的:

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

    但不可以这样:

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. @media print {
    6. .seriousError {
    7. // INVALID EXTEND: .error is used outside of the "@media print" directive
    8. @extend .error;
    9. border-width: 3px;
    10. }
    11. }

    希望有一天,浏览器可以原生支持 指令,这样就可以在任何指令中使用延伸功能,不再受限制了。

    7.4. @at-root

    The -root directive causes one or more rules to be emitted at the root of the document, rather than being nested beneath their parent selectors. It can either be used with a single inline selector:

    1. .parent {
    2. ...
    3. @at-root .child { ... }
    4. }

    Which would produce:

    1. .parent { ... }
    2. .child { ... }

    Or it can be used with a block containing multiple selectors:

    1. .parent {
    2. ...
    3. @at-root {
    4. .child1 { ... }
    5. .child2 { ... }
    6. }
    7. .step-child { ... }
    8. }

    Which would output the following:

    1. .parent { ... }
    2. .child1 { ... }
    3. .child2 { ... }
    4. .parent .step-child { ... }

    7.4.1. @at-root (without: …) and -root (with: …)

    By default, @at-root just excludes selectors. However, it’s also possible to use -root to move outside of nested directives such as @media as well. For example:

    1. @media print {
    2. .page {
    3. width: 8in;
    4. @at-root (without: media) {
    5. color: red;
    6. }
    7. }
    8. }

    produces:

    1. @media print {
    2. .page {
    3. width: 8in;
    4. }
    5. }
    6. .page {
    7. color: red;
    8. }

    You can use -root (without: …) to move outside of any directive. You can also do it with multiple directives separated by a space: @at-root (without: media supports) moves outside of both and @supports queries.

    There are two special values you can pass to -root. “rule” refers to normal CSS rules; @at-root (without: rule) is the same as -root with no query. @at-root (without: all) means that the styles should be moved outside of all directives and CSS rules.

    If you want to specify which directives or rules to include, rather than listing which ones should be excluded, you can use with instead of without. For example, -root (with: rule) will move outside of all directives, but will preserve any CSS rules.

    The @debug directive prints the value of a SassScript expression to the standard error output stream. It’s useful for debugging Sass files that have complicated SassScript going on. For example:

    1. @debug 10em + 12em;

    编译为

    1. Line 1 DEBUG: 22em

    7.6.

    The @warn directive prints the value of a SassScript expression to the standard error output stream. It’s useful for libraries that need to warn users of deprecations or recovering from minor mixin usage mistakes. There are two major distinctions between and @debug:

    • You can turn warnings off with the —quiet command-line option or the :quiet Sass option.
    • A stylesheet trace will be printed out along with the message so that the user being warned can see where their styles caused the warning. Usage Example:
    1. @mixin adjust-location($x, $y) {
    2. @if unitless($x) {
    3. @warn "Assuming #{$x} to be in pixels";
    4. $x: 1px * $x;
    5. }
    6. @if unitless($y) {
    7. @warn "Assuming #{$y} to be in pixels";
    8. $y: 1px * $y;
    9. }
    10. }

    The directive throws the value of a SassScript expression as a fatal error, including a nice stack trace. It’s useful for validating arguments to mixins and functions. For example: