@extend
指令是 Sass 中既強(qiáng)大易于誤解的指令。該指令作為一個(gè)警示,告知 Sass 對(duì)選擇器 A 的樣式化正好存在與選擇器B共通的地方。不用多說(shuō),這是書(shū)寫(xiě)模塊化 CSS 的好助手。
實(shí)際上,@extend
的實(shí)際作用是維護(hù)繼承前后選擇器之間的。這也就是說(shuō):
.foo > .bar
中 .bar
必須有一個(gè)父級(jí) .foo
);.baz { @extend .bar; }
會(huì)生成 .foo > .bar, .foo > .baz
);要理解這些現(xiàn)象,最直接的方式就是看看當(dāng)沒(méi)有限制時(shí)繼承樣式所產(chǎn)生的選擇器數(shù)量劇增的結(jié)果。如果 .baz .qux
繼承了 .foo .bar
,那么就會(huì)生成 .foo .baz .qux
或 .baz .foo .qux
,這是因?yàn)?.foo
和 .baz
是常見(jiàn)的選擇器,它們可以成為父級(jí)、祖父級(jí)等等。
始終使用選擇器占位符定義選擇器之間的關(guān)系,而不是類名,這能讓你更加輕松地更換命名約定。此外,因?yàn)檫x擇器之間的關(guān)系只被定義在了占位符中,所以很少會(huì)產(chǎn)生意料之外的選擇器。
當(dāng)繼承 .class
或 %placeholder
時(shí),如果父類和子類是同一類型,那么建議只使用 @extend
來(lái)實(shí)現(xiàn),比如 .error
是 .warning
的一種,那么 .error
就可以通過(guò) @extend .warning
來(lái)實(shí)現(xiàn)。
%button {
display: inline-block;
// … button styles
// Relationship: a %button that is a child of a %modal
%modal > & {
display: block;
}
}
.button {
@extend %button;
}
// Yep
.modal {
@extend %modal;
}
// Nope
.modal {
@extend %modal;
> .button {
@extend %button;
}
}
擴(kuò)展選擇器在許多情境下是有用和值得的。始終牢記下面這些規(guī)則,謹(jǐn)慎使用 @extend
指令:
%placeholders
,而不是具體的選擇器;.class
時(shí),只繼承單一的 .class
,不要使用[復(fù)雜選擇器]complex selector;%placeholders
;.foo .bar
)或者是常見(jiàn)的相鄰選擇器(比如:.foo ~ .bar
),否則會(huì)讓選擇器的數(shù)量急速增加。通常來(lái)說(shuō),@extend
有助于減少文件體積大小,因?yàn)樗牟僮鞅举|(zhì)上是合并選擇器而不是賦值樣式。話雖如此,當(dāng)你使用 Gzip 壓縮文件時(shí),@extend
對(duì)于文件壓縮的好處幾乎是可以忽略的。
這也就是說(shuō),如果你不能使用類似 Gzip 的工具,那么就可以考慮使用 @extend
來(lái)減少不必要的重復(fù),特別是當(dāng)樣式文件的大小成為性能瓶頸的時(shí)候,這種方式尤為有效。
應(yīng)該只在同一個(gè)媒體查詢作用域下繼承選擇器,將媒體查詢視為一種對(duì)作用域的限制。
%foo {
content: 'foo';
}
// Nope
@media print {
.bar {
// This doesn't work. Worse: it crashes.
@extend %foo;
}
}
// Yep
@media print {
.bar {
@at-root (without: media) {
@extend %foo;
}
}
}
// Yep
%foo {
content: 'foo';
&-print {
@media print {
content: 'foo print';
}
}
}
@media print {
.bar {
@extend %foo-print;
}
}
有關(guān) @extend
的好與壞,開(kāi)發(fā)者們之間的觀點(diǎn)大有不同,你可以閱讀以下文章了解其中的利弊:
總而言之,我建議只將 @extend
用于維護(hù)選擇器之間的關(guān)系。如果兩個(gè)選擇器是類似的,那么最好使用 @extend
;如果它們之間沒(méi)有關(guān)系,只是具有相同的樣式,那么使用 @mixin
會(huì)更好。更多有關(guān)兩者的用法,請(qǐng)看這篇文章:When to use extend and when to use a mixin.
感謝 David Khourshid 對(duì)本節(jié)提供的技術(shù)支持。