Sass 继承、占位符和混合宏

很多初学者刚刚接触的时候,都容易纠结什么时候用混合宏,什么时候用继承,然后什么时候用占位符。其实,这3个都有它们自身的优缺点。这一节我们来详细探讨一下这3个在实际开发中的不同。

由于“继承@extend”和“占位符%placeholder”都是属于继承的2种输出方式,这一节我们姑且把这两者统称为“继承”,然后再与混合宏比较。

继承、占位符和混合宏的声明方式和调用方式
方法 声明方式 调用方式
继承 .class @extend
占位符 %placeholder @extend
混合宏 @mixin @include

 

一、继承与混合宏

对于继承(包括@extend和%placeholder)和混合宏,我们总结出以下几点:

  • (1)继承和混合宏都能实现相同代码块的重用,极大提高开发效率;
  • (2)继承的使用一般不存在代码冗余,而混合宏的使用会存在代码冗余;
  • (3)继承不可以传递参数,而混合宏可以传递参数;

我们先来看几个例子,然后再从中对比一下继承与混合宏的区别。

举例1:使用继承来实现

.spriteAll
{
    bakckground:url(images/sprite.png) no-repeat;
}
.sprite-1
{
    @extend .spriteAll;
    background-position:0 -30px;
}
.sprite-2
{
    @extend .spriteAll;
    background-position:0 -60px;
}

编译出来的CSS代码如下:

.spriteAll, .sprite-1, .sprite-2
{
    bakckground: url(images/sprite.png) no-repeat;
}
.sprite-1
{
    background-position: 0 -30px;
}
.sprite-2
{
    background-position: 0 -60px;
}

举例2:使用混合宏来实现

@mixin spriteAll
{
    bakckground:url(images/sprite.png) no-repeat;
}
.sprite-1
{
    @include @spriteAll;
    background-position:0 -30px;
}
.sprite-2
{
    @include @spriteAll;
    background-position:0 -60px;
}

编译出来的CSS代码如下:

.sprite-1
{
    bakckground: url(images/sprite.png) no-repeat;
    background-position: 0 -30px;
}
.sprite-2
{
    bakckground: url(images/sprite.png) no-repeat;
    background-position: 0 -60px;
}

分析:

从上面两个例子,我们可以很清楚地看出混合宏有一个致命的缺点:编译出来的CSS不会把相同的代码块合并,造成代码冗余。

虽然混合宏有代码冗余的缺点,但是它也有一个明显的优点,那就是:可以使用传递参数的方式来封装功能代码块。

举例:

@mixin textCenter($height)
{
    height:$height;
    line-height:$height;
    text-align:center;
}
#div1
{
    @include textCenter(20px);
    width:100px;
}
#div2
{
    @include textCenter(40px);
    width:200px;
}

编译出来的CSS代码如下:

#div1
{
    height: 20px;
    line-height: 20px;
    text-align: center;
    width: 100px;
}
#div2
{
    height: 40px;
    line-height: 40px;
    text-align: center;
    width: 200px;
}

分析:

上面这个例子,如果要使用继承就无能为力了。在实际开发的过程中,对于“功能代码块”(类似于JavaScript中的函数)我们都是使用混合宏来实现的,因为功能代码块往往是可以通过传递不同的参数来满足我们开发的不同需求。

 

二、“继承@extend”和“占位符%placeholder”

从之前的学习我们知道,“占位符%placeholder”并非用来替换“继承@extend”的,而是用来配合“继承@extend”来使用的。也就是说,继承@extend有2种输出方式:

  • (1)需要保留基类的:只使用@extend来实现;
  • (2)不需要保留基类的:使用@extend配合%placeholder来实现;

这个我们很好理解,小伙伴们回去翻一翻“Sass占位符”这一节就知道了,这里不再重复说明。