-
Notifications
You must be signed in to change notification settings - Fork 0
/
sass.html
1545 lines (1422 loc) · 71.6 KB
/
sass.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<div id="article-content">
<h1 id="top"><a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html" target="_blank">Sass (Syntactically Awesome StyleSheets)</a></h1>
<p>Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 <a href="http://compass-style.org/">Compass</a>)有助于更好地组织管理样式文件,以及更高效地开发项目。</p>
<h2 id="t1">1. 特色功能 (Features)</h2>
<ul>
<li>完全兼容 CSS3</li>
<li>在 CSS 基础上增加变量、嵌套 (nesting)、混合 (mixins) 等功能</li>
<li>通过<a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html">函数</a>进行颜色值与属性值的运算</li>
<li>提供<a href="#t8">控制指令 (control directives)</a>等高级功能</li>
<li>自定义输出格式</li>
</ul>
<h2 id="t2">2. 语法格式 (Syntax)</h2>
<p>Sass 有两种语法格式。首先是 SCSS (Sassy CSS) —— 也是本文示例所使用的格式 —— 这种格式仅在 CSS3 语法的基础上进行拓展,所有 CSS3 语法在 SCSS 中都是通用的,同时加入 Sass 的特色功能。此外,SCSS 也支持大多数 CSS hacks 写法以及浏览器前缀写法 (vendor-specific syntax),以及早期的 IE 滤镜写法。这种格式以 <code>.scss</code> 作为拓展名。</p>
<p>另一种也是最早的 Sass 语法格式,被称为缩进格式 (Indented Sass) 通常简称 "Sass",是一种简化格式。它使用 “缩进” 代替 “花括号” 表示属性属于某个选择器,用 “换行” 代替 “分号” 分隔属性,很多人认为这样做比 SCSS 更容易阅读,书写也更快速。缩进格式也可以使用 Sass 的全部功能,只是与 SCSS 相比个别地方采取了不同的表达方式,具体请查看 <a href="http://sass-lang.com/docs/yardoc/file.INDENTED_SYNTAX.html">the indented syntax reference</a>。这种格式以 <code>.sass</code> 作为拓展名。</p>
<p>任何一种格式可以直接 <a href="#t7-1">导入 (@import)</a> 到另一种格式中使用,或者通过 <code>sass-convert</code> 命令行工具转换成另一种格式:</p>
<pre><code># Convert Sass to SCSS
$ sass-convert style.sass style.scss
# Convert SCSS to Sass
$ sass-convert style.scss style.sass
</code></pre><h2 id="t3">3. 使用 Sass (Using Sass)</h2>
<p>Sass 可以通过以下三种方式使用:作为命令行工具;作为独立的 Ruby 模块 (Ruby module);或者作为 Rack-enabled 框架的插件(例如 Ruby on Rails 与 Merb)。无论哪种方式都需要先安装 Sass gem (Windows 系统需要先<a href="http://rubyinstaller.org/">安装 Ruby</a>):</p>
<pre><code>gem install sass
</code></pre><p>在命令行中运行 Sass:</p>
<pre><code>sass input.scss output.css
</code></pre><p>监视单个 Sass 文件,每次修改并保存时自动编译:</p>
<pre><code>sass --watch input.scss:output.css
</code></pre><p>监视整个文件夹:</p>
<pre><code>sass --watch app/sass:public/stylesheets
</code></pre><p>更多命令的用法请通过 <code>sass --help</code> 获取帮助。</p>
<p>在 Ruby 中使用 Sass 也非常容易,Sass gem 安装完毕后运行 <code>require "sass"</code> 然后按照下面的方法使用 <a href="http://sass-lang.com/docs/yardoc/Sass/Engine.html">Sass::Engine</a>:</p>
<pre><code>engine = Sass::Engine.new("#main {background-color: #0000ff}", :syntax => :scss)
engine.render #=> "#main { background-color: #0000ff; }\n"
</code></pre><h3 id="t3-1">3.1. Rack/Rails/Merb Plugin</h3>
<p>在 Rails 3 之前的版本中使用 Sass,需要在 <code>environment.rb</code> 文件中添加:</p>
<pre><code>config.gem "sass"
</code></pre><p>Rails 3 则需要在 Gemfile 中添加:</p>
<pre><code>gem "sass"
</code></pre><p>在 Merb 中使用 Sass,需要在 <code>config/dependencies.rb</code> 中添加:</p>
<pre><code>dependency "merb-haml"
</code></pre><p>在 Rack 中使用 Sass,需要在 <code>config.ru</code> 中添加:</p>
<pre><code>require 'sass/plugin/rack'
use Sass::Plugin::Rack
</code></pre><p>样式文件与 views 不同,不包含任何动态内容,因此 CSS 只需要在 Sass 文件被修改后再编译生成。默认情况下 <code>.sass</code> 与 <code>.scss</code> 文件放置在 <code>public/stylesheets/sass</code> 中(可通过 <a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#template_location-option">:template_location</a> 修改路径),编译生成的 CSS 文件放置在 <code>public/stylesheets</code> 中。例如 <code>public/stylesheets/sass/main.scss</code> 编译生成 <code>public/stylesheets/main.css</code>。</p>
<h3 id="t3-2">3.2. 缓存 (Caching)</h3>
<p>Sass 自动缓存编译后的模板与 <a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#partials">partials</a>,这样做能够显著提升重新编译的速度,尤其在处理由 <code>@import</code> 导入多个子文件的大型项目时。</p>
<p>单独使用 Sass,缓存内容保存在 <code>.sass-cache</code> 文件夹中。在 Rails 和 Merb 项目中缓存文件保存在 <code>tmp/sass-cache</code> 文件夹中(可通过 <a href=""><code>:cache_location</code></a> 修改路径)。禁用缓存可将 <code>:cache</code> 设为 <code>false</code>。</p>
<h3 id="t3-3">3.3. 配置选项 (Options)</h3>
<p><a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#options">暂未翻译</a></p>
<h3 id="t3-4">3.4. 判断语法格式 (Syntax Selection)</h3>
<p>Sass 命令行工具根据文件的拓展名判断所使用的语法格式,没有文件名时 <code>sass</code> 命令默认编译 <code>.sass</code> 文件,添加 <code>--scss</code> 选项或者使用 <code>scss</code> 命令编译 SCSS 文件。</p>
<h3 id="t3-5">3.5. 编码格式 (Encodings)</h3>
<p>在 Ruby 1.9 及以上环境中运行 Sass 时,Sass 对文件的编码格式比较敏感,首先会根据 <a href="http://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#determine-the-fallback-encoding">CSS spec</a> 判断样式文件的编码格式,如果失败则检测 Ruby string encoding。也就是说,Sass 首先检查 Unicode byte order mark,然后是 <code>@charset</code> 声明,最后是 Ruby string encoding,假如都没有检测到,默认使用 UTF-8 编码。</p>
<p>与 CSS 相同,使用 <code>@charset</code> 可以声明特定的编码格式。在样式文件的起始位置(前面没有任何空白与注释)插入 <code>@charset "encoding-name"</code>, Sass 将会按照给出的编码格式编译文件。注意所使用的编码格式必须可转换为 Unicode 字符集。</p>
<p>Sass 以 UTF-8 编码输出 CSS 文件,当且仅当编译后的文件中包含非 ASCII 字符时,才会在输出文件中添加 <code>@charset</code> 声明,而在压缩模式下 (compressed mode) 使用 UTF-8 byte order mark 代替 <code>@charset</code> 声明语句。</p>
<h2 id="t4">4. CSS 功能拓展 (CSS Extensions)</h2>
<h3 id="t4-1">4.1. 嵌套规则 (Nested Rules)</h3>
<p>Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,例如:</p>
<pre><code class="lang-scss">#main p {
color: #00ff00;
width: 97%;
.redbox {
background-color: #ff0000;
color: #000000;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main p {
color: #00ff00;
width: 97%; }
#main p .redbox {
background-color: #ff0000;
color: #000000; }
</code></pre>
<p>嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理:</p>
<pre><code class="lang-scss">#main {
width: 97%;
p, div {
font-size: 2em;
a { font-weight: bold; }
}
pre { font-size: 3em; }
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
width: 97%; }
#main p, #main div {
font-size: 2em; }
#main p a, #main div a {
font-weight: bold; }
#main pre {
font-size: 3em; }
</code></pre>
<h3 id="t4-2">4.2. 父选择器 <code>&</code> (Referencing Parent Selectors: <code>&</code>)</h3>
<p>在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 <code>hover</code> 样式时,或者当 <code>body</code> 元素有某个 classname 时,可以用 <code>&</code> 代表嵌套规则外层的父选择器。</p>
<pre><code class="lang-scss">a {
font-weight: bold;
text-decoration: none;
&:hover { text-decoration: underline; }
body.firefox & { font-weight: normal; }
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">a {
font-weight: bold;
text-decoration: none; }
a:hover {
text-decoration: underline; }
body.firefox a {
font-weight: normal; }
</code></pre>
<p>编译后的 CSS 文件中 <code>&</code> 将被替换成嵌套外层的父选择器,如果含有多层嵌套,最外层的父选择器会一层一层向下传递:</p>
<pre><code class="lang-scss">#main {
color: black;
a {
font-weight: bold;
&:hover { color: red; }
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
color: black; }
#main a {
font-weight: bold; }
#main a:hover {
color: red; }
</code></pre>
<p><code>&</code> 必须作为选择器的第一个字符,其后可以跟随后缀生成复合的选择器,例如</p>
<pre><code class="lang-scss">#main {
color: black;
&-sidebar { border: 1px solid; }
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
color: black; }
#main-sidebar {
border: 1px solid; }
</code></pre>
<p>当父选择器含有不合适的后缀时,Sass 将会报错。</p>
<h3 id="t4-3">4.3. 属性嵌套 (Nested Properties)</h3>
<p>有些 CSS 属性遵循相同的命名空间 (namespace),比如 <code>font-family, font-size, font-weight</code> 都以 <code>font</code> 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中,例如:</p>
<pre><code class="lang-scss">.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold; }
</code></pre>
<p>命名空间也可以包含自己的属性值,例如:</p>
<pre><code class="lang-scss">.funky {
font: 20px/24px {
family: fantasy;
weight: bold;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.funky {
font: 20px/24px;
font-family: fantasy;
font-weight: bold; }
</code></pre>
<h3 id="t4-4">4.4. 占位符选择器 <code>%foo</code> (Placeholder Selectors: <code>%foo</code>)</h3>
<p>Sass 额外提供了一种特殊类型的选择器:占位符选择器 (placeholder selector)。与常用的 id 与 class 选择器写法相似,只是 <code>#</code> 或 <code>.</code> 替换成了 <code>%</code>。必须通过 <a href="#t7-3">@extend</a> 指令调用,更多介绍请查阅 <a href="#t7-3-6">@extend-Only Selectors</a>。</p>
<p>当占位符选择器单独使用时(未通过 <code>@extend</code> 调用),不会编译到 CSS 文件中。</p>
<h2 id="t5">5. 注释 <code>/* */</code> 与 <code>//</code> (Comments: <code>/* */</code> and <code>//</code>)</h2>
<p>Sass 支持标准的 CSS 多行注释 <code>/* */</code>,以及单行注释 <code>//</code>,前者会
被完整输出到编译后的 CSS 文件中,而后者则不会,例如:</p>
<pre><code class="lang-scss">/* This comment is
* several lines long.
* since it uses the CSS comment syntax,
* it will appear in the CSS output. */
body { color: black; }
// These comments are only one line long each.
// They won't appear in the CSS output,
// since they use the single-line comment syntax.
a { color: green; }
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">/* This comment is
* several lines long.
* since it uses the CSS comment syntax,
* it will appear in the CSS output. */
body {
color: black; }
a {
color: green; }
</code></pre>
<p>将 <code>!</code> 作为多行注释的第一个字符表示在压缩输出模式下保留这条注释并输出到 CSS 文件中,通常用于添加版权信息。</p>
<p>插值语句 (interpolation) 也可写进多行注释中输出变量值:</p>
<pre><code class="lang-scss">$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">/* This CSS is generated by My Snazzy Framework version 1.2.3. */
</code></pre>
<h2 id="t6">6. SassScript</h2>
<p>在 CSS 属性的基础上 Sass 提供了一些名为 SassScript 的新功能。 SassScript 可作用于任何属性,允许属性使用变量、算数运算等额外功能。</p>
<p>通过 interpolation,SassScript 甚至可以生成选择器或属性名,这一点对编写 mixin 有很大帮助。</p>
<h3 id="t6-1">6.1. Interactive Shell</h3>
<p>Interactive Shell 可以在命令行中测试 SassScript 的功能。在命令行中输入 <code>sass -i</code>,然后输入想要测试的 SassScript 查看输出结果:</p>
<pre><code>$ sass -i
>> "Hello, Sassy World!"
"Hello, Sassy World!"
>> 1px + 1px + 1px
3px
>> #777 + #777
#eeeeee
>> #777 + #888
white
</code></pre><h3 id="t6-2">6.2. 变量 <code>$</code> (Variables: <code>$</code>)</h3>
<p>SassScript 最普遍的用法就是变量,变量以美元符号开头,赋值方法与 CSS 属性的写法一样:</p>
<pre><code class="lang-scss">$width: 5em;
</code></pre>
<p>直接使用即调用变量:</p>
<pre><code class="lang-css">#main {
width: $width;
}
</code></pre>
<p>变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 <code>!global</code> 声明:</p>
<pre><code class="lang-scss">#main {
$width: 5em !global;
width: $width;
}
#sidebar {
width: $width;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
width: 5em;
}
#sidebar {
width: 5em;
}
</code></pre>
<h3 id="t6-3">6.3. 数据类型 (Data Types)</h3>
<p>SassScript 支持 6 种主要的数据类型:</p>
<ul>
<li>数字,<code>1, 2, 13, 10px</code></li>
<li>字符串,有引号字符串与无引号字符串,<code>"foo", 'bar', baz</code></li>
<li>颜色,<code>blue, #04a3f9, rgba(255,0,0,0.5)</code></li>
<li>布尔型,<code>true, false</code></li>
<li>空值,<code>null</code></li>
<li>数组 (list),用空格或逗号作分隔符,<code>1.5em 1em 0 2em, Helvetica, Arial, sans-serif</code></li>
<li>maps, 相当于 JavaScript 的 object,<code>(key1: value1, key2: value2)</code></li>
</ul>
<p>SassScript 也支持其他 CSS 属性值,比如 Unicode 字符集,或 <code>!important</code> 声明。然而Sass 不会特殊对待这些属性值,一律视为无引号字符串。</p>
<h4 id="t6-3-1">6.3.1. 字符串 (Strings)</h4>
<p>SassScript 支持 CSS 的两种字符串类型:有引号字符串 (quoted strings),如 <code>"Lucida Grande"</code> <code>'http://sass-lang.com'</code>;与无引号字符串 (unquoted strings),如 <code>sans-serif</code> <code>bold</code>,在编译 CSS 文件时不会改变其类型。只有一种情况例外,使用 <code>#{}</code> (interpolation) 时,有引号字符串将被编译为无引号字符串,这样便于在 mixin 中引用选择器名:</p>
<pre><code class="lang-scss">@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">body.firefox .header:before {
content: "Hi, Firefox users!"; }
</code></pre>
<h4 id="t6-3-2">6.3.2. 数组 (Lists)</h4>
<p>数组 (lists) 指 Sass 如何处理 CSS 中 <code>margin: 10px 15px 0 0</code> 或者 <code>font-face: Helvetica, Arial, sans-serif</code> 这样通过空格或者逗号分隔的一系列的值。事实上,独立的值也被视为数组 —— 只包含一个值的数组。</p>
<p>数组本身没有太多功能,但 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#list-functions">Sass list functions</a> 赋予了数组更多新功能:<code>nth</code> 函数可以直接访问数组中的某一项;<code>join</code> 函数可以将多个数组连接在一起;<code>append</code> 函数可以在数组中添加新值;而 <code>@each</code> 指令能够遍历数组中的每一项。</p>
<p>数组中可以包含子数组,比如 <code>1px 2px, 5px 6px</code> 是包含 <code>1px 2px</code> 与 <code>5px 6px</code> 两个数组的数组。如果内外两层数组使用相同的分隔方式,需要用圆括号包裹内层,所以也可以写成 <code>(1px 2px) (5px 6px)</code>。变化是,之前的 <code>1px 2px, 5px 6px</code> 使用逗号分割了两个子数组 (comma-separated),而 <code>(1px 2px) (5px 6px)</code> 则使用空格分割(space-separated)。</p>
<p>当数组被编译为 CSS 时,Sass 不会添加任何圆括号(CSS 中没有这种写法),所以 <code>(1px 2px) (5px 6px)</code> 与 <code>1px 2px, 5px 6px</code> 在编译后的 CSS 文件中是完全一样的,但是它们在 Sass 文件中却有不同的意义,前者是包含两个数组的数组,而后者是包含四个值的数组。</p>
<p>用 <code>()</code> 表示不包含任何值的空数组(在 Sass 3.3 版之后也视为空的 map)。空数组不可以直接编译成 CSS,比如编译 <code>font-family: ()</code> Sass 将会报错。如果数组中包含空数组或空值,编译时将被清除,比如 <code>1px 2px () 3px</code> 或 <code>1px 2px null 3px</code>。</p>
<p>基于逗号分隔的数组允许保留结尾的逗号,这样做的意义是强调数组的结构关系,尤其是需要声明只包含单个值的数组时。例如 <code>(1,)</code> 表示只包含 <code>1</code> 的数组,而 <code>(1 2 3,)</code> 表示包含 <code>1 2 3</code> 这个以空格分隔的数组的数组。</p>
<h4 id="t6-3-3">6.3.3. Maps</h4>
Maps represent an association between keys and values, where keys are used to look up values. They make it easy to collect values into named groups and access those groups dynamically. They have no direct parallel in CSS, although they’re syntactically similar to media query expressions:
<code>scss
$map: (key1: value1, key2: value2, key3: value3);</code>
Unlike lists, maps must always be surrounded by parentheses and must always be comma-separated. Both the keys and values in maps can be any SassScript object. A map may only have one value associated with a given key (although that value may be a list). A given value may be associated with many keys, though.
Like lists, maps are mostly manipulated using SassScript functions. The map-get function looks up values in a map and the map-merge function adds values to a map. The @each directive can be used to add styles for each key/value pair in a map. The order of pairs in a map is always the same as when the map was created.
Maps can also be used anywhere lists can. When used by a list function, a map is treated as a list of pairs. For example, (key1: value1, key2: value2) would be treated as the nested list key1 value1, key2 value2 by list functions. Lists cannot be treated as maps, though, with the exception of the empty list. () represents both a map with no key/value pairs and a list with no elements.
Note that map keys can be any Sass data type (even another map) and the syntax for declaring a map allows arbitrary SassScript expressions that will be evaluated to determine the key.
Maps cannot be converted to plain CSS. Using one as the value of a variable or an argument to a CSS function will cause an error. Use the inspect($value) function to produce an output string useful for debugging maps.
<br>
中文简要说明:<br>
Maps可视为键值对的集合,键被用于定位值 在css种没有对应的概念。
和Lists不同Maps必须被圆括号包围,键值对被都好分割 。
Maps中的keys和values可以是sassscript的任何对象。(包括任意的sassscript表达式 arbitrary SassScript expressions)
和Lists一样Maps主要为sassscript函数服务,如 map-get函数用于查找键值,map-merge函数用于map和新加的键值融合,@each命令可添加样式到一个map中的每个键值对。
Maps可用于任何Lists可用的地方,在List函数中 Map会被自动转换为List ,
如 (key1: value1, key2: value2)会被List函数转换为 key1 value1, key2 value2
,反之则不能。(网友Soledad提供)
<h4 id="t6-3-4">6.3.4. 颜色 (Colors)</h4>
Any CSS color expression returns a SassScript Color value. This includes a large number of named colors which are indistinguishable from unquoted strings.
In compressed output mode, Sass will output the smallest CSS representation of a color. For example, #FF0000 will output as red in compressed mode, but blanchedalmond will output as #FFEBCD.
A common issue users encounter with named colors is that since Sass prefers the same output format as was typed in other output modes, a color interpolated into a selector becomes invalid syntax when compressed. To avoid this, always quote named colors if they are meant to be used in the construction of a selector.
<h3 id="t6-4">6.4. 运算 (Operations)</h3>
所有数据类型均支持相等运算 <code>==</code> 或 <code>!=</code>,此外,每种数据类型也有其各自支持的运算方式。
<h4 id="t6-4-1">6.4.1. 数字运算 (Number Operations)</h4>
<p>SassScript 支持数字的加减乘除、取整等运算 (<code>+, -, *, /, %</code>),如果必要会在不同单位间转换值。</p>
<pre><code class="lang-scss">p {
width: 1in + 8pt;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
width: 1.111in; }
</code></pre>
<p>关系运算 <code><, >, <=, >=</code> 也可用于数字运算,相等运算 <code>==, !=</code> 可用于所有数据类型。</p>
<h5 id="t6-4-1-1">6.4.1.1. 除法运算 <code>/</code> (Division and <code>/</code>)</h5>
<p><code>/</code> 在 CSS 中通常起到分隔数字的用途,SassScript 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了 <code>/</code> 除法运算的功能。也就是说,如果 <code>/</code> 在 SassScript 中把两个数字分隔,编译后的 CSS 文件中也是同样的作用。</p>
<p>以下三种情况 <code>/</code> 将被视为除法运算符号:</p>
<ul>
<li>如果值,或值的一部分,是变量或者函数的返回值</li>
<li>如果值被圆括号包裹</li>
<li>如果值是算数表达式的一部分</li>
</ul>
<pre><code class="lang-scss">p {
font: 10px/8px; // Plain CSS, no division
$width: 1000px;
width: $width/2; // Uses a variable, does division
width: round(1.5)/2; // Uses a function, does division
height: (500px/2); // Uses parentheses, does division
margin-left: 5px + 8px/2px; // Uses +, does division
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
font: 10px/8px;
width: 500px;
height: 250px;
margin-left: 9px; }
</code></pre>
<p>如果需要使用变量,同时又要确保 <code>/</code> 不做除法运算而是完整地编译到 CSS 文件中,只需要用 <code>#{}</code> 插值语句将变量包裹。</p>
<pre><code class="lang-scss">p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
font: 12px/30px; }
</code></pre>
<h4 id="t6-4-2">6.4.2. 颜色值运算 (Color Operations)</h4>
<p>颜色值的运算是分段计算进行的,也就是分别计算红色,绿色,以及蓝色的值:</p>
<pre><code class="lang-scss">p {
color: #010203 + #040506;
}
</code></pre>
<p>计算 <code>01 + 04 = 05</code> <code>02 + 05 = 07</code> <code>03 + 06 = 09</code>,然后编译为</p>
<pre><code class="lang-css">p {
color: #050709; }
</code></pre>
<p>使用 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html">color functions</a> 比计算颜色值更方便一些。</p>
<p>数字与颜色值之间也可以进行算数运算,同样也是分段计算的,比如</p>
<pre><code class="lang-scss">p {
color: #010203 * 2;
}
</code></pre>
<p>计算 <code>01 * 2 = 02</code> <code>02 * 2 = 04</code> <code>03 * 2 = 06</code>,然后编译为</p>
<pre><code class="lang-css">p {
color: #020406; }
</code></pre>
<p>需要注意的是,如果颜色值包含 alpha channel(rgba 或 hsla 两种颜色值),必须拥有相等的 alpha 值才能进行运算,因为算术运算不会作用于 alpha 值。</p>
<pre><code class="lang-scss">p {
color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
color: rgba(255, 255, 0, 0.75); }
</code></pre>
<p>颜色值的 alpha channel 可以通过 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#opacify-instance_method">opacify</a> 或 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#transparentize-instance_method">transparentize</a> 两个函数进行调整。</p>
<pre><code class="lang-scss">$translucent-red: rgba(255, 0, 0, 0.5);
p {
color: opacify($translucent-red, 0.3);
background-color: transparentize($translucent-red, 0.25);
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
color: rgba(255, 0, 0, 0.8);
background-color: rgba(255, 0, 0, 0.25); }
</code></pre>
<p>IE 滤镜要求所有的颜色值包含 alpha 层,而且格式必须固定 <code>#AABBCCDD</code>,使用 <code>ie_hex_str</code> 函数可以很容易地将颜色转化为 IE 滤镜要求的格式。</p>
<pre><code class="lang-scss">$translucent-red: rgba(255, 0, 0, 0.5);
$green: #00ff00;
div {
filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}');
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">div {
filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000);
}
</code></pre>
<h4 id="t6-4-3">6.4.3. 字符串运算 (String Operations)</h4>
<p><code>+</code> 可用于连接字符串</p>
<pre><code class="lang-scss">p {
cursor: e + -resize;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
cursor: e-resize; }
</code></pre>
<p>注意,如果有引号字符串(位于 <code>+</code> 左侧)连接无引号字符串,运算结果是有引号的,相反,无引号字符串(位于 <code>+</code> 左侧)连接有引号字符串,运算结果则没有引号。</p>
<pre><code class="lang-scss">p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p:before {
content: "Foo Bar";
font-family: sans-serif; }
</code></pre>
<p>运算表达式与其他值连用时,用空格做连接符:</p>
<pre><code class="lang-scss">p {
margin: 3px + 4px auto;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
margin: 7px auto; }
</code></pre>
<p>在有引号的文本字符串中使用 <code>#{}</code> 插值语句可以添加动态的值:</p>
<pre><code class="lang-scss">p:before {
content: "I ate #{5 + 10} pies!";
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p:before {
content: "I ate 15 pies!"; }
</code></pre>
<p>空的值被视作插入了空字符串:</p>
<pre><code class="lang-scss">$value: null;
p:before {
content: "I ate #{$value} pies!";
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p:before {
content: "I ate pies!"; }
</code></pre>
<h4 id="t6-4-4">6.4.4. 布尔运算 (Boolean Operations)</h4>
<p>SassScript 支持布尔型的 <code>and</code> <code>or</code> 以及 <code>not</code> 运算。</p>
<h4 id="t6-4-5">6.4.5. 数组运算 (List Operations)</h4>
<p>数组不支持任何运算方式,只能使用 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#list-functions">list functions</a> 控制。</p>
<h3 id="t6-5">6.5. 圆括号 (Parentheses)</h3>
<p>圆括号可以用来影响运算的顺序:</p>
<pre><code class="lang-scss">p {
width: 1em + (2em * 3);
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
width: 7em; }
</code></pre>
<h3 id="t6-6">6.6. 函数 (Functions)</h3>
<p>SassScript 定义了多种函数,有些甚至可以通过普通的 CSS 语句调用:</p>
<pre><code class="lang-scss">p {
color: hsl(0, 100%, 50%);
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
color: #ff0000; }
</code></pre>
<h4 id="t6-6-1">6.6.1. 关键词参数 (Keyword Arguments)</h4>
<p>Sass 函数允许使用关键词参数 (keyword arguments),上面的例子也可以写成:</p>
<pre><code class="lang-scss">p {
color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
}
</code></pre>
<p>虽然不够简明,但是阅读起来会更方便。关键词参数给函数提供了更灵活的接口,以及容易调用的参数。关键词参数可以打乱顺序使用,如果使用默认值也可以省缺,另外,参数名被视为变量名,下划线、短横线可以互换使用。</p>
<p>通过 <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html">Sass::Script::Functions</a> 查看完整的 Sass 函数列表,参数名,以及如何自定义函数。</p>
<h3 id="t6-7">6.7. 插值语句 <code>#{}</code> (Interpolation: <code>#{}</code>)</h3>
<p>通过 <code>#{}</code> 插值语句可以在选择器或属性名中使用变量:</p>
<pre><code class="lang-scss">$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p.foo {
border-color: blue; }
</code></pre>
<p><code>#{}</code> 插值语句也可以在属性值中插入 SassScript,大多数情况下,这样可能还不如使用变量方便,但是使用 <code>#{}</code> 可以避免 Sass 运行运算表达式,直接编译 CSS。</p>
<pre><code class="lang-scss">p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">p {
font: 12px/30px; }
</code></pre>
<h3 id="t6-8">6.8. <code>&</code> in SassScript</h3>
<p>Just like when it’s used in selectors, & in SassScript refers to the current parent selector. It’s a comma-separated list of space-separated lists. For example:</p>
<pre><code class="lang-scss">.foo.bar .baz.bang, .bip.qux {
$selector: &;
}
</code></pre>
<p>The value of $selector is now ((".foo.bar" ".baz.bang"), ".bip.qux"). The compound selectors are quoted here to indicate that they’re strings, but in reality they would be unquoted. Even if the parent selector doesn’t contain a comma or a space, & will always have two levels of nesting, so it can be accessed consistently.</p>
<p>If there is no parent selector, the value of & will be null. This means you can use it in a mixin to detect whether a parent selector exists:</p>
<pre><code class="lang-scss">@mixin does-parent-exist {
@if & {
&:hover {
color: red;
}
} @else {
a {
color: red;
}
}
}
</code></pre>
<h3 id="t6-9">6.9. 变量定义 <code>!default</code> (Variable Defaults: <code>!default</code>)</h3>
<p>可以在变量的结尾添加 <code>!default</code> 给一个未通过 <code>!default</code> 声明赋值的变量赋值,此时,如果变量已经被赋值,不会再被重新赋值,但是如果变量还没有被赋值,则会被赋予新的值。</p>
<pre><code class="lang-scss">$content: "First content";
$content: "Second content?" !default;
$new_content: "First time reference" !default;
#main {
content: $content;
new-content: $new_content;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
content: "First content";
new-content: "First time reference"; }
</code></pre>
<p>变量是 null 空值时将视为未被 <code>!default</code> 赋值。</p>
<pre><code class="lang-scss">$content: null;
$content: "Non-null content" !default;
#main {
content: $content;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#main {
content: "Non-null content"; }
</code></pre>
<h2 id="t7">7. @-Rules 与指令 (@-Rules and Directives)</h2>
<p>Sass 支持所有的 CSS3 @-Rules,以及 Sass 特有的 “指令”(directives)。这一节会详细解释,更多资料请查看 <a href="#8">控制指令 (control directives)</a> 与 <a href="#9">混合指令 (mixin directives)</a> 两个部分。</p>
<h3 id="t7-1">7.1. @import</h3>
<p>Sass 拓展了 <code>@import</code> 的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。</p>
<p>Sass 在当前地址,或 Rack, Rails, Merb 的 Sass 文件地址寻找 Sass 文件,如果需要设定其他地址,可以用 <code>:load_paths</code> 选项,或者在命令行中输入 <code>--load-path</code> 命令。</p>
<p>通常,<code>@import</code> 寻找 Sass 文件并将其导入,但在以下情况下,<code>@import</code> 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。</p>
<ul>
<li>文件拓展名是 <code>.css</code>;</li>
<li>文件名以 <code>http://</code> 开头;</li>
<li>文件名是 <code>url()</code>;</li>
<li><code>@import</code> 包含 media queries。</li>
</ul>
<p>如果不在上述情况内,文件的拓展名是 <code>.scss</code> 或 <code>.sass</code>,则导入成功。没有指定拓展名,Sass 将会试着寻找文件名相同,拓展名为 <code>.scss</code> 或 <code>.sass</code> 的文件并将其导入。</p>
<pre><code class="lang-scss">@import "foo.scss";
</code></pre>
<p>或</p>
<pre><code class="lang-scss">@import "foo";
</code></pre>
<p>都会导入文件 foo.scss,但是</p>
<pre><code class="lang-scss">@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);
</code></pre>
<p>Sass 允许同时导入多个文件,例如同时导入 rounded-corners 与 text-shadow 两个文件:</p>
<pre><code class="lang-scss">@import "rounded-corners", "text-shadow";
</code></pre>
<p>导入文件也可以使用 <code>#{ }</code> 插值语句,但不是通过变量动态导入 Sass 文件,只能作用于 CSS 的 <code>url()</code> 导入方式:</p>
<pre><code class="lang-scss">$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=\#{$family}");
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
</code></pre>
<h4 id="7-1-1">7.1.1. 分音 (Partials)</h4>
<p>如果需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要编译这些文件,但导入语句中却不需要添加下划线。</p>
<p>例如,将文件命名为 <code>_colors.scss</code>,便不会编译 <code>_colours.css</code> 文件。</p>
<pre><code class="lang-scss">@import "colors";
</code></pre>
<p>上面的例子,导入的其实是 <code>_colors.scss</code> 文件</p>
<p>注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。</p>
<h4 id="7-1-2">7.1.2. 嵌套 @import</h4>
<p>大多数情况下,一般在文件的最外层(不在嵌套规则内)使用 <code>@import</code>,其实,也可以将 <code>@import</code> 嵌套进 CSS 样式或者 <code>@media</code> 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中。</p>
<p>假设 example.scss 文件包含以下样式:</p>
<pre><code class="lang-scss">.example {
color: red;
}
</code></pre>
<p>然后导入到 <code>#main</code> 样式内</p>
<pre><code class="lang-scss">#main {
@import "example";
}
</code></pre>
<p>将会被编译为</p>
<pre><code class="lang-css">#main .example {
color: red;
}
</code></pre>
<blockquote>
<p>Directives that are only allowed at the base level of a document, like @mixin or @charset, are not allowed in files that are @imported in a nested context. 这一句不理解</p>
</blockquote>
<p>不可以在混合指令 (mixin) 或控制指令 (control directives) 中嵌套 <code>@import</code>。</p>
<h3 id="t7-2">7.2. @media</h3>
<p>Sass 中 <code>@media</code> 指令与 CSS 中用法一样,只是增加了一点额外的功能:允许其在 CSS 规则中嵌套。如果 <code>@media</code> 嵌套在 CSS 规则内,编译时,<code>@media</code> 将被编译到文件的最外层,包含嵌套的父选择器。这个功能让 <code>@media</code> 用起来更方便,不需要重复使用选择器,也不会打乱 CSS 的书写流程。</p>
<pre><code class="lang-scss">.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.sidebar {
width: 300px; }
@media screen and (orientation: landscape) {
.sidebar {
width: 500px; } }
</code></pre>
<p><code>@media</code> 的 queries 允许互相嵌套使用,编译时,Sass 自动添加 <code>and</code></p>
<pre><code class="lang-scss">@media screen {
.sidebar {
@media (orientation: landscape) {
width: 500px;
}
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">@media screen and (orientation: landscape) {
.sidebar {
width: 500px; } }
</code></pre>
<p><code>@media</code> 甚至可以使用 SassScript(比如变量,函数,以及运算符)代替条件的名称或者值:</p>
<pre><code class="lang-scss">$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
@media #{$media} and ($feature: $value) {
.sidebar {
width: 500px;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar {
width: 500px; } }
</code></pre>
<h3 id="t7-3">7.3. @extend</h3>
<p>在设计网页的时候常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在 HTML 中给元素定义两个 class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:</p>
<pre><code class="lang-markup"><div class="error seriousError">
Oh no! You've been hacked!
</div>
</code></pre>
<p>样式如下</p>
<pre><code class="lang-css">.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
</code></pre>
<p>麻烦的是,这样做必须时刻记住使用 <code>.seriousError</code> 时需要参考 <code>.error</code> 的样式,带来了很多不变:智能比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。使用 <code>@extend</code> 可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。</p>
<pre><code class="lang-scss">.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
</code></pre>
<p>上面代码的意思是将 <code>.error</code> 下的所有样式继承给 <code>.seriousError</code>,<code>border-width: 3px;</code> 是单独给 <code>.seriousError</code> 设定特殊样式,这样,使用 <code>.seriousError</code> 的地方可以不再使用 <code>.error</code>。</p>
<p>其他使用到 <code>.error</code> 的样式也会同样继承给 <code>.seriousError</code>,例如,另一个样式 <code>.error.intrusion</code> 使用了 <code>hacked.png</code> 做背景,<code><div class="seriousError intrusion"></code> 也同样会使用 <code>hacked.png</code> 背景。</p>
<pre><code class="lang-css">.error.intrusion {
background-image: url("/image/hacked.png");
}
</code></pre>
<h4 id="7-3-1">7.3.1. How it Works</h4>
<p><code>@extend</code> 的作用是将重复使用的样式 (<code>.error</code>) 延伸 (extend) 给需要包含这个样式的特殊样式(<code>.seriousError</code>),刚刚的例子:</p>
<pre><code class="lang-scss">.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.error.intrusion, .seriousError.intrusion {
background-image: url("/image/hacked.png"); }
.seriousError {
border-width: 3px; }
</code></pre>
<p>当合并选择器时,<code>@extend</code> 会很聪明地避免无谓的重复,<code>.seriousError.seriousError</code> 将编译为 <code>.seriousError</code>,不能匹配任何元素的选择器(比如 <code>#main#footer</code> )也会删除。</p>
<h4 id="7-3-2">7.3.2. 延伸复杂的选择器 (Extending Complex Selectors)</h4>
<p>Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 <code>.special.cool</code>,<code>a:hover</code> 或者 <code>a.user[href^="http://"]</code> 等,例如:</p>
<pre><code class="lang-scss">.hoverlink {
@extend a:hover;
}
</code></pre>
<p>同 class 元素一样,<code>a:hover</code> 的样式将继承给 <code>.hoverlink</code>。</p>
<pre><code class="lang-scss">.hoverlink {
@extend a:hover;
}
a:hover {
text-decoration: underline;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">a:hover, .hoverlink {
text-decoration: underline; }
</code></pre>
<p>与上面 <code>.error.intrusion</code> 的例子一样,所有 <code>a:hover</code> 的样式将继承给 <code>.hoverlink</code>,包括其他使用到 <code>a:hover</code> 的样式,例如:</p>
<pre><code class="lang-scss">.hoverlink {
@extend a:hover;
}
.comment a.user:hover {
font-weight: bold;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.comment a.user:hover, .comment .user.hoverlink {
font-weight: bold; }
</code></pre>
<h4 id="7-3-3">7.3.3. 多重延伸 (Multiple Extends)</h4>
<p>同一个选择器可以延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器:</p>
<pre><code class="lang-scss">.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error;
@extend .attention;
border-width: 3px;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.attention, .seriousError {
font-size: 3em;
background-color: #ff0; }
.seriousError {
border-width: 3px; }
</code></pre>
<p>每个 <code>.seriousError</code> 将包含 <code>.error</code> 与 <code>.attention</code> 下的所有样式,这时,后定义的样式享有优先权:<code>.seriousError</code> 的背景颜色是 <code>#ff0</code> 而不是 <code>#fdd</code>,因为 <code>.attention</code> 在 <code>.error</code> 之后定义。</p>
<p>多重延伸可以使用逗号分隔选择器名,比如 <code>@extend .error, .attention;</code> 与 <code>@extend .error;</code> <code>@extend.attention</code> 有相同的效果。</p>
<h4 id="7-3-4">7.3.4. 继续延伸 (Chaining Extends)</h4>
<p>当一个选择器延伸给第二个后,可以继续将第二个选择器延伸给第三个,例如:</p>
<pre><code class="lang-scss">.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%;
}
</code></pre>
<p>现在,每个 <code>.seriousError</code> 选择器将包含 <code>.error</code> 的样式,而 <code>.criticalError</code> 不仅包含 <code>.seriousError</code> 的样式也会同时包含 <code>.error</code> 的所有样式,上面的代码编译为:</p>
<pre><code class="lang-css">.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%; }
</code></pre>
<h4 id="7-3-5">7.3.5. 选择器列 (Selector Sequences)</h4>
<p>暂时不可以将选择器列 (Selector Sequences),比如 <code>.foo .bar</code> 或 <code>.foo + .bar</code>,延伸给其他元素,但是,却可以将其他元素延伸给选择器列:</p>
<pre><code class="lang-scss">#fake-links .link {
@extend a;
}
a {
color: blue;
&:hover {
text-decoration: underline;
}
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">a, #fake-links .link {
color: blue; }
a:hover, #fake-links .link:hover {
text-decoration: underline; }
</code></pre>
<h5 id="7-3-5-1">7.3.5.1. 合并选择器列 (Merging Selector Sequences)</h5>
<p>有时会遇到复杂的情况,比如选择器列中的某个元素需要延伸给另一个选择器列,这种情况下,两个选择器列需要合并,比如:</p>
<pre><code class="lang-scss">#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
</code></pre>
<p>技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,上面这个简单的例子就可能有 10 种结果。所以,Sass 只会编译输出有用的选择器。</p>
<p>当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前:</p>
<pre><code class="lang-scss">#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
font-weight: bold; }
</code></pre>
<p>如果两个列 (sequence) 包含了相同的选择器,相同部分将会合并在一起,其他部分交替输出。在下面的例子里,两个列都包含 <code>#admin</code>,输出结果中它们合并在了一起:</p>
<pre><code class="lang-scss">#admin .tabbar a {
font-weight: bold;
}
#admin .overview .fakelink {
@extend a;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#admin .tabbar a,
#admin .tabbar .overview .fakelink,
#admin .overview .tabbar .fakelink {
font-weight: bold; }
</code></pre>
<h4 id="7-3-6">7.3.6. @extend-Only 选择器 (@extend-Only Selectors)</h4>
<p>有时,需要定义一套样式并不是给某个元素用,而是只通过 <code>@extend</code> 指令使用,尤其是在制作 Sass 样式库的时候,希望 Sass 能够忽略用不到的样式。</p>
<p>如果使用普通的 CSS 规则,最后会编译出很多用不到的样式,也容易与其他样式名冲突,所以,Sass 引入了“占位符选择器” (placeholder selectors),看起来很像普通的 <code>id</code> 或 <code>class</code> 选择器,只是 <code>#</code> 或 <code>.</code> 被替换成了 <code>%</code>。可以像 class 或者 id 选择器那样使用,当它们单独使用时,不会被编译到 CSS 文件中。</p>
<pre><code class="lang-scss">// This ruleset won't be rendered on its own.
#context a%extreme {
color: blue;
font-weight: bold;
font-size: 2em;
}
</code></pre>
<p>占位符选择器需要通过延伸指令使用,用法与 class 或者 id 选择器一样,被延伸后,占位符选择器本身不会被编译。</p>
<pre><code class="lang-scss">.notice {
@extend %extreme;
}
</code></pre>
<p>编译为</p>
<pre><code class="lang-css">#context a.notice {
color: blue;
font-weight: bold;
font-size: 2em; }
</code></pre>
<h4 id="7-3-7">7.3.7. <code>!optional</code> 声明 (The <code>!optional</code> Flag)</h4>
<p>如果 <code>@extend</code> 失败会收到错误提示,比如,这样写 <code>a.important {@extend .notice}</code>,当没有 <code>.notice</code> 选择器时,将会报错,只有 <code>h1.notice</code> 包含 <code>.notice</code> 时也会报错,因为 <code>h1</code> 与 <code>a</code> 冲突,会生成新的选择器。</p>
<p>如果要求 <code>@extend</code> 不生成新选择器,可以通过 <code>!optional</code> 声明达到这个目的,例如:</p>
<pre><code class="lang-scss">a.important {
@extend .notice !optional;
}
</code></pre>
<h4 id="7-3-8">7.3.8. 在指令中延伸 (@extend in Directives)</h4>
<p>在指令中使用 <code>@extend</code> 时(比如在 <code>@media</code> 中)有一些限制:Sass 不可以将 <code>@media</code> 层外的 CSS 规则延伸给指令层内的 CSS,这样会生成大量的无用代码。也就是说,如果在 <code>@media</code> (或者其他 CSS 指令)中使用 <code>@extend</code>,必须延伸给相同指令层中的选择器。</p>
<p>下面的例子是可行的:</p>
<pre><code class="lang-scss">@media print {
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
}
</code></pre>
<p>但不可以这样:</p>
<pre><code class="lang-scss">.error {
border: 1px #f00;
background-color: #fdd;
}
@media print {
.seriousError {
// INVALID EXTEND: .error is used outside of the "@media print" directive
@extend .error;
border-width: 3px;