五、混合宏
当你的样式变得越来越复杂,需要重复使用大段的样式时, Sass 中的混合宏就会有重大意义。
声明混合宏(使用@mixin来声明)
1.不带参数的混合宏:
@mixin border-radius{ -webkit-border-radius: 5px; border-radius: 5px; }
2.带参数的混合宏:
@mixin border-radius($radius:5px){ -webkit-border-radius: $radius; border-radius: $radius; }
3.复杂的混合宏
@mixin box-shadow($shadow...) { @if length($shadow) >= 1 { @include prefixer(box-shadow, $shadow); } @else{ $shadow:0 0 4px rgba(0,0,0,.3); @include prefixer(box-shadow, $shadow); } }
这个 box-shadow 的混合宏,带有多个参数,这个时候可以使用“ … ”来替代。简单的解释一下,当 $shadow 的参数数量值大于或等于“ 1 ”时,表示有多个阴影值,反之调用默认的参数值“ 0 0 4px rgba(0,0,0,.3) ”。
调用混合宏(使用@include来调用混合宏)
调用1.中声明的混合宏:
button { @include border-radius; }
编译后的css为:
button { -webkit-border-radius: 3px; border-radius: 3px; }
混合宏的参数
1.传一个不带值的参数
在混合宏中,可以传一个不带任何值的参数,如:
@mixin border-radius($radius){ -webkit-border-radius: $radius; border-radius: $radius; }
调用时,可以给这个混合宏传一个参数值:
.box { @include border-radius(3px); } 编译后的css为: .box { -webkit-border-radius: 3px; border-radius: 3px; }
2.传一个带值的参数
在混合宏中,可以给参数传一个默认值,如:
@mixin border-radius($radius:3px){ -webkit-border-radius: $radius; border-radius: $radius; }
调用时:
.btn { @include border-radius; //调用默认的3px的值 } .box { @include border-radius(50%); //将会覆盖掉默认值 }
3.传多个参数
例如:
@mixin center($width,$height){ width: $width; height: $height; position: absolute; top: 50%; left: 50%; margin-top: -($height) / 2; margin-left: -($width) / 2; }
调用时:
.box-center { @include center(500px,300px); }
还有一个特别的参数“…”,当混合宏参数过多时使用,如:
@mixin box-shadow($shadows...){ @if length($shadows) >= 1 { -webkit-box-shadow: $shadows; box-shadow: $shadows; } @else { $shadows: 0 0 2px rgba(#000,.25); -webkit-box-shadow: $shadow; box-shadow: $shadow; } }
调用时:
.box { @include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2)); } 编译出来的css为: .box { -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); }
扩展/继承(通过@extend实现)
在 Sass 中是通过关键词 “@extend”来继承已存在的类样式块,从而实现代码的继承。编译后的css会将选择器合并在一起,形成组合选择器,如下所示:
.btn { border: 1px solid #ccc; padding: 6px 10px; font-size: 14px; } .btn-primary { background-color: #f36; color: #fff; @extend .btn; } .btn-second { background-color: orange; color: #fff; @extend .btn; }
编译后的css为:
.btn, .btn-primary, .btn-second { border: 1px solid #ccc; padding: 6px 10px; font-size: 14px; } .btn-primary { background-color: #f36; color: #fff; } .btn-second { background-clor: orange; color: #fff; }
占位符(%placeholder)
它可以取代以前 CSS 中的基类造成的代码冗余的情形。因为 %placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。通过 @extend 调用的占位符,编译出来的代码会将相同的代码合并在一起。来看一个演示:
%mt5 { margin-top: 5px; } %pt5{ padding-top: 5px; } .btn { @extend %mt5; @extend %pt5; } .block { @extend %mt5; span { @extend %pt5; } }
编译后为:
.btn, .block { margin-top: 5px; } .btn, .block span { padding-top: 5px; }
混合宏VS继承VS占位符
1.混合宏:
编译出来的 CSS 清晰告诉了大家,他不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余,这也是 CSSer 无法忍受的一件事情。不过他并不是一无事处,他可以传参数。
个人建议:如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。
2.继承:
使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,比如 .mt, .block, .block span, .header, .header span。这样编译出来的代码相对于混合宏来说要干净的多,也是 CSSer 期望看到。但是他不能传变量参数。
个人建议:如果你的代码块不需要专任何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。
3.占位符
编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。”