混合器
混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left
。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。
混合指令的用法是在 @mixin
后添加名称与样式,比如名为 large-text
的混合通过下面的代码定义:
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
混合也需要包含选择器和属性,甚至可以用 &
引用父选择器:
@mixin clearfix {
display: inline-block;
&:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html & { height: 1px }
}
引用混合样式 @include
使用 @include
指令引用混合样式,格式是在其后添加混合名称,以及需要的参数(可选)
@include
调用会把混合器中的所有样式提取出来放在 @include
被调用的地方。
//scss
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
//css
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px;
}
也可以在最外层引用混合样式,不会直接定义属性,也不可以使用父选择器。
//scss
@mixin silly-links {
a {
color: blue;
background-color: red;
}
}
@include silly-links;
//css
a {
color: blue;
background-color: red; }
混合样式中也可以包含其他混合样式,比如
@mixin compound {
@include highlighted-background;
@include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
混合样式中应该只定义后代选择器,这样可以安全的导入到文件的任何位置。
混合器中使用css规则
混合器中不仅可以包含属性,也可以包含 ss 规则,包含选择器和选择器中的属性,如下代码:
@mixin nav-ul {
list-style: none;
li{
list-style-image: none;
list-style-type: none;
padding: 10px;
}
}
当一个包含 css 规则的混合器通过 @include
包含在一个父规则中时,在混合器中的规则最终会生成父规则中嵌套规则。
举个例子,看看下边的 sass 代码,这个例子中使用了 nav-ul 这个混合器
ul.plan{
color: aqua;
@include nav-ul;
}
sass的 @include
指令会将引入混合器的那行代码替换成混合器里边的内容。
混合器传参
当混合器被 @include 时,你可以把它当作一个css 函数来传参。如果你像下边这样写:
//scss
a{
@include colors(red,green ,yellow );
}
//css
a{
color: red;
}
a:hover {
color: green;
}
a:visited {
color: yellow;
}
参数默认值及参数的顺序问题
当你 @include
混合器时,有时候可能会很难区分每个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass 允许通过语法$name: value
的形式指定每个参数的值。这种形式的传参,参数顺序就不必再在乎了,只需要保证没有漏掉参数即可:
@mixin colorss($normal,$hover:$normal,$visited:$normal) {
color: $normal;
&:hover{
color: $hover;
}
&:visited{
color: $visited;
}
}
a{
@include colorss(red);
}
选择器继承的使用
在设计网页的时候常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在 HTML 中给元素定义两个 class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:
<div class="error seriousError">
Oh no! You've been hacked!
</div>
样式如下
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
麻烦的是,这样做必须时刻记住使用 .seriousError
时需要参考 .error
的样式,带来了很多不变:智能比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。使用 @extend
可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
上面代码的意思是将 .error
下的所有样式继承给 .seriousError
,border-width: 3px;
是单独给 .seriousError
设定特殊样式,这样,使用 .seriousError
的地方可以不再使用 .error
。
其他使用到 .error
的样式也会同样继承给 .seriousError
,例如,另一个样式 .error.intrusion
使用了 hacked.png
做背景,<div class="seriousError intrusion">
也同样会使用 hacked.png
背景。
.error.intrusion {
background-image: url("/image/hacked.png");
}
使用 sass 的时候,最后一个减少重复的主要特性就是选择器继承,基于 Nicole Sullivan
面向对象的 css 的理念,选择器继承是说一个选择器可以继承为另一个选择器定义的所有样式
。这个通过 @extend 语法实现
选择器继承html元素
任何 css 规则都可以继承其他规则,几乎任何 css 规则也都可以被继承。大多数情况你可能只想对类使用继承,但是有些场合你可能想做得更多。最常用的一种高级用法是继承一个 html 元素的样式。尽管默认的浏览器样式不会被继承,因为它们不属于样式表中的样式,但是你对 html元素添加的所有样式都会被继承。
继承的细节
关于@extend 有两个要点你应该知道。
- 跟混合器相比,继承生成的CSs 代码相对更少。因为继承仅仅是重复选择器,而不会重复属性,所以使用继承往往比混合器生成的css 体积更小。如果你非常关心你站点的速度,请牢记这一点。
- 继承遵从css 层叠的规则。当两个不同的 css 规则应用到同一个html 元素上时,并这两个不同的css 规则对同一属性的修饰不同的值,css 层叠规则会决定应用哪个样式。相当直观:通常权重更高的选择器胜出,如果权重相同,定义在后边的规则胜出。混合器本身不会引起 css 层叠问题,因为混合器把样式直接放到了css 规则中,而继承存在样式层叠的问题。被继承的样式会保持原有定义位置和选择器权重不变。通常来说这并不会引起什么问题,但是知道这点总没有坏处。
继承的最佳实践
是不要在 css 规则中使用后代选择器(比如 ,foo ,bar) 去承 SS 规则。如果你这么做,同时被继承的css 规则有通过后代选择器修饰的样式,生成css 中的选择器的数量很快就会失控:
.baz{}
.foo .bar {
@extend .baz;
}
.bip .baz {
color: red;
}