摘錄自Understanding placeholder selectors.
@extend
@extend
讓你能夠在多個選擇器中通過繼承的方式共享一段樣式:
.icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@extend .icon;
/* error specific styles... */
}
.info-icon {
@extend .icon;
/* info specific styles... */
}
會被轉化為:
.icon, .error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/* error specific styles... */
}
.info-icon {
/* info specific styles... */
}
有個問題就是, 如果你不可能用到icon
這個類呢?
占位符選擇器%
占位符選擇器(Placeholder Selector)是以%
而不是.
作為開始符的選擇器. 它自身不會出現在編譯后的CSS文件中, 只會出現在@extend
了它的那些選擇器中.
上例中, 用%icon
替換.icon
會得到:
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/* error specific styles... */
}
.info-icon {
/* info specific styles... */
}
CSS中不會出現.icon
類!
@extend
vs. @include
乍看下, %
選擇器和無參數mixin差不多, 在瀏覽器中產生的效果是一樣的, 但是編譯后的CSS有很大不同.
@mixin icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@include icon;
/* error specific styles... */
}
.info-icon {
@include icon;
/* info specific styles... */
}
以上代碼會編譯成
.error-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/* error specific styles... */
}
.info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/* info specific styles... */
}
可以看到, .error-icon
和.info-icon
中繼承自mixinicon
的部分重復了兩次, 有冗余. 但是用%
選擇器配合@extend
就不會有這樣的問題.
@extend
的限制
@extend
有個限制, 就是你不能@extend
不同@media
塊中的樣式. 這個限制同樣對%
選擇器有效.
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
@media screen {
.error-icon {
@extend %icon;
}
.info-icon {
@extend %icon;
}
}
這會導致編譯錯誤:
You may not @extend an outer selector from within @media.
You may only @extend selectors within the same directive.
From "@extend %icon" on line 8 of icons.scss
這是由於@extend
的實現方式其實是用調用@extend
的類替換被@extend
的類, 上例中即用.error-icon, .info-icon
替換%icon
. 但是由於這些調用@extend
的類屬於@media
塊, 這樣直接替換會導致替換后的規則脫離@media
塊, 因此是非法的.
但是, 反過來就沒事兒. 因為%icon
屬性原本就是在@media
內部生效的, .error-icon, .info-icon
繼承來的這部分規則自然也只應該在該@media
下生效.
@media screen {
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
}
.error-icon {
@extend %icon;
background-color: red;
}
.info-icon {
@extend %icon;
background-color: green;
}
會被編譯成
@media screen {
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
}
.error-icon {
background-color: red;
}
.info-icon {
background-color: green;
}