1.申明和使用变量
sass
使用$
符号来标识变量(老版本的sass
使用!
来标识变量),比如$highlight-color
和$sidebar-width。
与CSS
属性不同,变量可以在css
规则块定义之外存在。当变量定义在css
规则块内,那么该变量只能在此规则块内使用。如果它们出现在任何形式的{...}
块中(如@media
或者@font-face
块),情况也是如此:
1 $nav-color: #F90; 2 nav { 3 $width: 100px; 4 width: $width; 5 color: $nav-color; 6 } 7 8 //编译后 9 10 nav { 11 width: 100px; 12 color: #F90; 13 }
2、变量名用中划线还是下划线分隔
sass
的变量名可以与css
中的属性名和选择器名称相同,包括中划线和下划线,sass中两种方式相同。
3.属性嵌套
1 nav { 2 border: { 3 style: solid; 4 width: 1px; 5 color: #ccc; 6 } 7 }
嵌套属性的规则是这样的:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }
块,把子属性部分写在这个{ }
块中。就像css
选择器嵌套一样,sass
会把你的子属性一一解开,把根属性和子属性部分通过中划线-连接起来,最后生成的效果与你手动一遍遍写的css
样式一样:
1 nav { 2 border-style: solid; 3 border-width: 1px; 4 border-color: #ccc; 5 }
对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则:
1 nav { 2 border: 1px solid #ccc { 3 left: 0px; 4 right: 0px; 5 } 6 } 7 //这比下边这种同等样式的写法要好: 8 9 nav { 10 border: 1px solid #ccc; 11 border-left: 0px; 12 border-right: 0px; 13 }
4.和css@import的区别
css
有一个特别不常用的特性,即@import
规则,它允许在一个css
文件中导入其他css
文件。然而,后果是只有执行到@import
时,浏览器才会去下载其他css
文件,这导致页面加载起来特别慢。
sass
也有一个@import
规则,但不同的是,sass
的@import
规则在生成css
文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css
文件中,而无需发起额外的下载请求。
使用sass
的@import
规则并不需要指明被导入文件的全名。你可以省略.sass
或.scss
文件后缀
5.使用SASS部分文件
当通过@import
把sass
样式分散到多个文件时,你通常只想生成少数几个css
文件。那些专门为@import
命令而编写的sass
文件,并不需要生成对应的独立css
文件,这样的sass
文件称为局部文件。对此,sass
有一个特殊的约定来命名这些文件。
此约定即,sass
局部文件的文件名以下划线开头。这样,sass
就不会在编译时单独编译这个文件输出css
,而只把这个文件用作导入。当你@import
一个局部文件时,还可以不写文件的全名,即省略文件名开头的下划线。
这一条和less一样。
6.默认变量值
一般情况下,你反复声明一个变量,只有最后一处声明有效且它会覆盖前边的值。举例说明:
1 $link-color: blue; 2 $link-color: red; 3 a { 4 color: $link-color; 5 }
在上边的例子中,超链接的color
会被设置为red。
使用sass
的!default
标签可以实现这个目的。它很像css
属性中!important
标签的对立面,不同的是!default
用于变量,含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。
7.嵌套导入
跟原生的css
不同,sass
允许@import
命令写在css
规则内。这种导入方式下,生成对应的css
文件时,局部文件会被直接插入到css
规则内导入它的地方。举例说明,有一个名为_blue-theme.scss
的局部文件,内容如下:
1 aside { 2 background: blue; 3 color: white; 4 }
然后把它导入到一个CSS规则内,如下所示:
1 .blue-theme {@import "blue-theme"} 2 3 //生成的结果跟你直接在.blue-theme选择器内写_blue-theme.scss文件的内容完全一样。 4 5 .blue-theme { 6 aside { 7 background: blue; 8 color: #fff; 9 } 10 }
8.静默注释
sass
另外提供了一种不同于css
标准注释格式/* ... */
的注释语法,即静默注释,其内容不会出现在生成的css
文件中。静默注释的语法跟JavaScript
Java
等类C
的语言中单行注释的语法相同,它们以//
开头,注释内容直到行末。
1 body { 2 color: #333; // 这种注释内容不会出现在生成的css文件中 3 padding: 0; /* 这种注释内容会出现在生成的css文件中 */ 4 }
9.混合器 △△△
如果你的整个网站中有几处小小的样式类似(例如一致的颜色和字体),那么使用变量来统一处理这种情况是非常不错的选择。但是当你的样式变得越来越复杂,你需要大段大段的重用样式的代码,独立的变量就没办法应付这种情况了。你可以通过sass
的混合器实现大段样式的重用。
混合器使用@mixin
标识符定义。看上去很像其他的CSS @
标识符,比如说@media
或者@font-face
。这个标识符给一大段样式赋予一个名字,这样你就可以轻易地通过引用这个名字重用这段样式。下边的这段sass
代码,定义了一个非常简单的混合器,目的是添加跨浏览器的圆角边框。
1 @mixin rounded-corners { 2 -moz-border-radius: 5px; 3 -webkit-border-radius: 5px; 4 border-radius: 5px; 5 }
然后就可以在你的样式表中通过@include
来使用这个混合器,放在你希望的任何地方。@include
调用会把混合器中的所有样式提取出来放在@include
被调用的地方。如果像下边这样写:
1 notice { 2 background-color: green; 3 border: 2px solid #00aa00; 4 @include rounded-corners; 5 } 6 7 //sass最终生成: 8 9 .notice { 10 background-color: green; 11 border: 2px solid #00aa00; 12 -moz-border-radius: 5px; 13 -webkit-border-radius: 5px; 14 border-radius: 5px; 15 }
在.notice
中的属性border-radius
-moz-border-radius
和-webkit-border-radius
全部来自rounded-corners
这个混合器。
10.何时使用
判断一组属性是否应该组合成一个混合器,一条经验法则就是你能否为这个混合器想出一个好的名字。
如果你找不到,这时候构造一个混合器可能并不合适。
有时候仅仅把属性放在混合器中还远远不够,可喜的是,sass
同样允许你把css
规则放在混合器中。
11.混合器中的CSS规则
混合器中不仅可以包含属性,也可以包含css
规则,包含选择器和选择器中的属性,如下代码:
1 @mixin no-bullets { 2 list-style: none; 3 li { 4 list-style-image: none; 5 list-style-type: none; 6 margin-left: 0px; 7 } 8 }
当一个包含css
规则的混合器通过@include
包含在一个父规则中时,在混合器中的规则最终会生成父规则中的嵌套规则。举个例子,看看下边的sass
代码,这个例子中使用了no-bullets
这个混合器:
1 ul.plain { 2 color: #444; 3 @include no-bullets; 4 } 5 //sass的@include指令会将引入混合器的那行代码替换成混合器里边的内容。 6 //最终,上边的例子如下代码: 7 8 ul.plain { 9 color: #444; 10 list-style: none; 11 } 12 ul.plain li { 13 list-style-image: none; 14 list-style-type: none; 15 margin-left: 0px; 16 }
混合器中的规则甚至可以使用sass
的父选择器标识符&
。使用起来跟不用混合器时一样,sass
解开嵌套规则时,用父规则中的选择器替代&
。
12.给混合器传参
@include
混合器时,参数其实就是可以赋值给css
属性值的变量
1 @mixin link-colors($normal, $hover, $visited) { 2 color: $normal; 3 &:hover { color: $hover; } 4 &:visited { color: $visited; } 5 }
当你@include混合器时,有时候可能会很难区分每个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass
允许通过语法$name: value
的形式指定每个参数的值。这种形式的传参,参数顺序就不必再在乎了,只需要保证没有漏掉参数即可:
1 a { 2 @include link-colors( 3 $normal: blue, 4 $visited: green, 5 $hover: red 6 ); 7 }
13.默认参数值
为了在@include
混合器时不必传入所有的参数,我们可以给参数指定一个默认值。参数默认值使用$name: default-value
的声明形式,默认值可以是任何有效的css
属性值,甚至是其他参数的引用,如下代码:
1 @mixin link-colors( 2 $normal, 3 $hover: $normal, 4 $visited: $normal 5 ) 6 { 7 color: $normal; 8 &:hover { color: $hover; } 9 &:visited { color: $visited; } 10 }
14.使用选择器继承来精简CSS
通过@extend
语法实现
1 //通过选择器继承继承样式 2 .error { 3 border: 1px solid red; 4 background-color: #fdd; 5 } 6 .seriousError { 7 @extend .error; 8 border-width: 3px; 9 }
在上边的代码中,.seriousError
将会继承样式表中任何位置处为.error
定义的所有样式。以class="seriousError"
修饰的html
元素最终的展示效果就好像是class="seriousError error"
。相关元素不仅会拥有一个3px
宽的边框,而且这个边框将变成红色的,这个元素同时还会有一个浅红色的背景,因为这些都是在.error
里边定义的样式。
.seriousError
不仅会继承.error
自身的所有样式,任何跟.error
有关的组合选择器样式也会被.seriousError
以组合选择器的形式继承,如下代码:
1 //.seriousError从.error继承样式 2 .error a{ //应用到.seriousError a 3 color: red; 4 font-weight: 100; 5 } 6 h1.error { //应用到hl.seriousError 7 font-size: 1.2rem; 8 }
15.何时使用继承
当一个元素拥有的类(比如说.seriousError
)表明它属于另一个类(比如说.error
),这时使用继承再合适不过了。结合Java、php的继承
16.继承的高级用法
任何css
规则都可以继承其他规则,几乎任何css
规则也都可以被继承。大多数情况你可能只想对类使用继承,但是有些场合你可能想做得更多。最常用的一种高级用法是继承一个html
元素的样式。尽管默认的浏览器样式不会被继承,因为它们不属于样式表中的样式,但是你对html
元素添加的所有样式都会被继承。
接下来的这段代码定义了一个名为disabled
的类,样式修饰使它看上去像一个灰掉的超链接。通过继承a这一超链接元素来实现:
1 .disabled { 2 color: gray; 3 @extend a; 4 }
假如一条样式规则继承了一个复杂的选择器,那么它只会继承这个复杂选择器命中的元素所应用的样式。举例来说, 如果.seriousError
@extend
.important.error
, 那么.important.error
和h1.important.error
的样式都会被.seriousError
继承, 但是.important
或者.error下
的样式则不会被继承。这种情况下你很可能希望.seriousError
能够分别继承.important
或者.error
下的样式。
如果一个选择器序列(#main .seriousError
)@extend
另一个选择器(.error
),那么只有完全匹配#main .seriousError
这个选择器的元素才会继承.error
的样式,就像单个类 名继承那样。拥有class="seriousError"
的#main
元素之外的元素不会受到影响。
像#main .error
这种选择器序列是不能被继承的。这是因为从#main .error
中继承的样式一般情况下会跟直接从.error
中继承的样式基本一致,细微的区别往往使人迷惑。
现在你已经了解了通过继承能够做些什么事情,接下来我们将学习继承的工作细节,在生成对应css
的时候,sass
具体干了些什么事情。
17.继承的工作细节
跟变量和混合器不同,继承不是仅仅用css
样式替换@extend处的代码那么简单。为了不让你对生成的css
感觉奇怪,对这背后的工作原理有一定了解是非常重要的。
@extend
背后最基本的想法是,如果.seriousError @extend .error
, 那么样式表中的任何一处.error
都用.error
.seriousError
这一选择器组进行替换。这就意味着相关样式会如预期那样应用到.error
和.seriousError
。当.error
出现在复杂的选择器中,比如说h1.error
.error a
或者#main .sidebar input.error[type="text"]
,那情况就变得复杂多了,但是不用担心,sass
已经为你考虑到了这些。
关于@extend
有两个要点你应该知道。
- 跟混合器相比,继承生成的
css
代码相对更少。因为继承仅仅是重复选择器,而不会重复属性,所以使用继承往往比混合器生成的css
体积更小。如果你非常关心你站点的速度,请牢记这一点。 - 继承遵从
css
层叠的规则。当两个不同的css
规则应用到同一个html
元素上时,并且这两个不同的css
规则对同一属性的修饰存在不同的值,css
层叠规则会决定应用哪个样式。相当直观:通常权重更高的选择器胜出,如果权重相同,定义在后边的规则胜出。
混合器本身不会引起css
层叠的问题,因为混合器把样式直接放到了css
规则中,而继承存在样式层叠的问题。被继承的样式会保持原有定义位置和选择器权重不变。通常来说这并不会引起什么问题,但是知道这点总没有坏处。
18.使用继承的最佳实践
通常使用继承会让你的css
美观、整洁。因为继承只会在生成css
时复制选择器,而不会复制大段的css
属性。但是如果你不小心,可能会让生成的css
中包含大量的选择器复制。
避免这种情况出现的最好方法就是不要在css
规则中使用后代选择器(比如.foo .bar
)去继承css
规则。如果你这么做,同时被继承的css
规则有通过后代选择器修饰的样式,生成css
中的选择器的数量很快就会失控:
1 .foo .bar { @extend .baz; } 2 .bip .baz { a: b; }
在上边的例子中,sass
必须保证应用到.baz的样式同时也要应用到.foo .bar
(位于class="foo"的元素内的class="bar"的元素)。例子中有一条应用到.bip .baz
(位于class="bip"的元素内的class="baz"的元素)的css
规则。当这条规则应用到.foo .bar
时,可能存在三种情况,如下代码:
1 <!-- 继承可能迅速变复杂 --> 2 <!-- Case 1 --> 3 <div class="foo"> 4 <div class="bip"> 5 <div class="bar">...</div> 6 </div> 7 </div> 8 <!-- Case 2 --> 9 <div class="bip"> 10 <div class="foo"> 11 <div class="bar">...</div> 12 </div> 13 </div> 14 <!-- Case 3 --> 15 <div class="foo bip"> 16 <div class="bar">...</div> 17 </div>
为了应付这些情况,sass
必须生成三种选择器组合(仅仅是.bip .foo .bar不能覆盖所有情况)。如果任何一条规则里边的后代选择器再长一点,sass
需要考虑的情况就会更多。实际上sass
并不总是会生成所有可能的选择器组合,即使是这样,选择器的个数依然可能会变得相当大,所以如果允许,尽可能避免这种用法。
值得一提的是,只要你想,你完全可以放心地继承有后代选择器修饰规则的选择器,不管后代选择器多长,但有一个前提就是,不要用后代选择器去继承。
小结
本文介绍了sass
最基本部分,你可以轻松地使用sass
编写清晰、无冗余、语义化的css
。对于sass
提供的工具你已经有了一个比较深入的了解,同时也掌握了何时使用这些工具的指导原则。
变量是sass
提供的最基本的工具。通过变量可以让独立的css
值变得可重用,无论是在一条单独的规则范围内还是在整个样式表中。变量、混合器的命名甚至sass
的文件名,可以互换通用_
和-
。同样基础的是sass
的嵌套机制。嵌套允许css
规则内嵌套css
规则,减少重复编写常用的选择器,同时让样式表的结构一眼望去更加清晰。sass
同时提供了特殊的父选择器标识符&
,通过它可以构造出更高效的嵌套。
你也已经学到了sass
的另一个重要特性,样式导入。通过样式导入可以把分散在多个sass
文件中的内容合并生成到一个css
文件,避免了项目中有大量的css
文件通过原生的css
@import
带来的性能问题。通过嵌套导入和默认变量值,导入可以构建更强有力的、可定制的样式。混合器允许用户编写语义化样式的同时避免视觉层面上样式的重复。你不仅学到了如何使用混合器减少重复,同时学习到了如何使用混合器让你的css
变得更加可维护和语义化。最后,我们学习了与混合器相辅相成的选择器继承。继承允许你声明类之间语义化的关系,通过这些关系可以保持你的css
的整洁和可维护性。
参考链接:https://www.sass.hk/guide/