前面我们已经知道sass中的变量了。
但是变量能记录的毕竟只是一个值,顶多把一个属性的所有值全部记录进去。
比如这样:
这样固然可以让box这个选择器很轻松地获得一个边框样式。
但是如果我有大量公用的样式呢?比如文字颜色,字体大小这些东西其实都可以统一起来。
那这时候如果我们再一条一条的去存变量,然后再去使用的话就不太方便了。
混合(Mixin)就是用来解决这个问题的,它可以把一整段代码打包,然后像一个变量一样在其他地方使用。
今天,咱们就来详细解读一下Sass的混合功能。
Sass的混合操作
混合在官方的解释是这样的:
混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class。
混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则。
甚至通过参数功能引入变量,输出多样化的样式。
来看案例:
考虑图中按钮的实现,咱先用以前的方法来写:
可以看到,以上代码中虽然我们大量用了变量。
但是两个选择器里面内容的相似度依然非常高。
大家可能在想:
明明border-radius、font、text-align都可以用变量来定义,但是仔细想想,这样的代码真的是我们需要的么?
稍微复杂点就全都是变量?
这恐怕会越写越乱吧!
所以面对这样的代码,我们就需要用到混合了
来看看混合的“神”操作
现在我们来看看用混合怎么写
可以看到这代码一下就变得很清晰了。我们来看看这段代码里发生了什么事情:
第一段,利用@mixin指令创建了一个“超级变量”:btn。
而这个“超级变量”是一个集合,集合里面可以写所有的css规则。
然后通过@include指令引用这个“超级变量”。
这样我们就做到了把几个相似选择器中重复的代码提取出来,达到了代码的高复用性。
而sass把这个定义“超级变量”, 和引用“超级变量”叫做混合。
当然在这之前我们可能会考虑写一个公用的class。
然后在需要的地方去引入这个class就可以了。
但是那样的代码毕竟可维护性不高,性能也是肯定不如sass的,而且sass的混合还有更加强大的地方。
那怎么办呢?接着往下看。
混合中的参数
在上面这段代码中,虽然我已经把重复的代码全部都提取出去了,但是剩下的两个属性:
border和padding两个选择器之间的差别也不太大。
那有没有可能把这两个属性也提取出来呢?
是可以的:
可以看到这段代码里,编译过后的代码和之前的代码是一样的。
但是sass代码又更加精简一些了 :
在定义混合样式 btn 的时候,在后面加上了一个括号,括号里其实就是一个变量名称。
但是这个变量并没有值。然后可以看到这个变量在下面用到了 :
border: 1px solid $color;
在这里用到了这个变量。
那么也就代表了:
在这个混合样式没有被调用的时候,这个border里面的$color是得不到值的。
只有当调用这个混合样式的时候,给它传入一个值,这时候border才能得到传入进来的值。
然后把传入进来的值替换到border这条样式上去。
再把自己作为一个整体替换到引入混合样式的地方。
这个过程看起来可能会有点复杂,我们简单点来说吧:
我们把这整个过程当做是去存物处取东西。
不同的客户拿着不同的钥匙来,那么取走的东西肯定也是不一样的。
但是存物处突然搞活动了,所有客户来取东西,都送一盒鸡蛋!
那么这时候我们整个过程就比较好理解了;
不同的客户(.btnGray、.btnBlue)拿着不同的钥匙(#899、#4395ff)来btn这个存物处这里取东西。
那么btn会根据不同的钥匙取出不同的东西(.btnGray得到的是:
border: 1px solid #899
而.btnBlue得到的是:
border: 1px solid #4395ff)
然后附赠一盒鸡蛋(公共样式)
最后.btnGray和.btnBlue都得到了公共样式,并且分别得到了颜色不一样的边框样式~
再来看上面这段代码:
从上到下解析,从1~7行一开始是不解析的。
因为在这期间它作为一个混合样式还没有被调用。所以不会解析
到第10行的时候看到了一个 @include指令,并且后面跟着的名称是 btn .
那这时候sass会去找有没有名字叫做btn的混合样式:
哎,貌似刚才经过的地方有这么个家伙,感觉有点眼熟,然后立马把1~7行的btn抓过来了:这里要调用你了!
再往后一看,哎哟,居然还需要钥匙,恰好第10行代码 btn的后面的括号里就有一个钥匙。
于是乎1~7行在这一瞬间就被替换成了这样:
然后再把这一段代码复制到第10行这个地方,于是选择器.btnGray就获得了完整的代码。
替换完成了之后 1~7行就立刻又恢复原样了。
代码继续往下走,走到第15行的时候,哎,这个地方还需要那哥们,于是btn又被拎过来了…
重复刚才的动作。
要注意的点:
定义了参数的混合样式,必须传入参数,否则会报错。
遇到多个参数怎么办?
到这里,混合这个东西似乎就比较清楚了。
不过细心的同学可能发现了,貌似两个选择器里的padding也可以这样操作呀?
是的,混合样式后面的的变量其实叫做参数。
参数用于给混合指令中的样式设定变量,并且赋值使用。
在定义混合指令的时候,按照变量的格式,通过逗号分隔,将参数写进圆括号里。
引用指令时,按照参数的顺序,再将所赋的值对应写进括号。
要注意的点:
多个参数在调用传值时,只能按照定义的顺序传入,中间不可缺少参数;
如果想要打乱顺序,则可以这样写:
如何设置参数的默认值?
甚至混合指令也可以使用给变量赋值的方法给参数设定默认值。
然后,当这个指令被引用的时候,如果没有给参数赋值,则自动使用默认值:
这样的话变量$color 和 $pad 就拥有默认值了,在调用的时候。
如果没有传入值,那么这两个变量将会得到这里定义的默认值:
要注意的点:
如果定义了多个变量,当只想改变其中一个变量时,可以指定变量名。
比如现在我们的混合样式已经带有默认值了,现在我需要让.btnGray的padding值变成10px
那要怎么办呢?
如果我们这样写:
这样无疑是错误的,所以我们可以指定其变量名
花钱都买不到的小技巧
在混合样式里,可以引入其他混合样式
可把整个选择器当做混合样式的一部分
这在代码模块化的时候非常有用~
不确定参数个数的时候,这样写