IT序号网

sass和less的几点不同知识解答

developer 2021年05月25日 编程语言 166 0

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部分文件

当通过@importsass样式分散到多个文件时,你通常只想生成少数几个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文件中。静默注释的语法跟JavaScriptJava等类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/


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

进程间通信之Linux信号量编程知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。