@extend的使用会产生如下结果
.a{
color: red
}
.b{
@extend .a;
}
<!--编译后-->
.a, .b {
color: red;
}
复制代码
如果我们把不希望@extend扩展的属性产生实质性的作用 ,只是想要单纯的使用它,就像mixin那样,应该怎么办?这个时候%(占位符)就登场了。%
代表任意的css选择器,%a
可能是.a
,#a
...。并且通过占位符编写的样式不会出现在编译后的文件中,除非通过@extend扩展。
看这个例子:
%aa{
color: red
}
.bb{
@extend %aa
}
.cc{
@extend %aa
}
<!--编译后-->
.cc, .bb {
color: red;
}
复制代码
通过观察我们发现%aa仅仅作为一个类似于样式变量的形式存在,并不会编译到css文件中。
并且,跟mixin有个很大的区别,@extend的样式并不会简单的复制到引用它的位置,而是通过合理的复用避免相同@extend
样式的重复。
在看一个奇怪的例子
.a .b%abc{
color: red;
}
.test .ccc{
@extend %abc;
}
复制代码
这段scss编译后的结果回事怎样的?
<!--编译后-->
.a .test .b.ccc, .test .a .b.ccc {
color: red;
}
复制代码
好像跟预想的不一样,实际上@extend是让一个选择器继承被引用的选择器的所有样式,包括其样式的作用域,被包含的样式等。有点类似于深拷贝的意思,相当于被继承样式的整个父子关系都被拷贝给继承样式。继承样式同样有自己的父子关系,要在一个继承样式上杂揉原有的父子关系和继承而来的父子关系,有的时候会产生不确定的情形,所以需要把所有的可能性都编译成css的结果。
上面的例子中,b%abc是在.a的作用域内起作用。而继承它的.ccc
是在·test
作用域内起作用,而.a .test .b.ccc, .test .a .b.cc
同时满足上述条件,所以必须将两种可能都考虑进来。
下面换一种写法:
.a>.b%abc{
color: red;
}
.test .ccc{
@extend %abc;
}
复制代码
可能我们就能猜到结果了,
.test .a > .b.ccc {
color: red;
}
复制代码
这是由于>
的加入让结果变得唯一确定。
在看一个例子
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
复制代码
编译的结果是会包含被引用样式的子样式的。
.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.error.intrusion, .seriousError.intrusion {
background-image: url("/image/hacked.png"); }
.seriousError {
border-width: 3px; }
复制代码