用@extend繼承復用樣式
回憶一下最上面的嵌套,嵌套的特點是,比如a嵌套b,a聲明的屬性,b是得不到的,而實踐中一些css屬性是不自動繼承的,所以有時候需要a的聲明讓b也聲明一次,怎么辦?用@extend繼承復用樣式。
a {
width: 100%;
}
b {
@extend a;
font-size: 12px;
}
會得到:
a, b {
width: 100%;
}
b {
font-size: 12px;
}
說白了,就是誰繼承了a,a的后面就把誰加上,加個逗號并列起來,以實現屬性的復用。
進階:占位選擇器%搭配@extend使用
這個需要仔細理解一下,比如我定義了五種顏色的按鈕,它們除了顏色和邊框的一些區別之外完全相同,我的一種選擇是先定義一個.btn,然后里面定義五種顏色,比如老外經常用的.danger、.warning、.error等等,我還有一種選擇就是先弄一個.danger, .warning, .error {}
,然后再分別.danger {}、.warning{}、.error{}。先不討論哪種更科學,只說如果我想實現后一種,可以怎么做?你會說那就直接寫個.danger, .warning, .error {}
,這里就有問題了,如果我將來不再以這些單詞作為class名,變成了red、green等等,這時候咋辦?就算沒變,我突然不再需要.danger這種警告色,我咋辦?刪好幾處代碼?No,我可以先弄一個虛假的選擇器,也就是占位選擇器:
%button-reset {
margin: 0;
padding: .5em 1.2em;
text-decoration: none;
cursor: pointer;
}
.save {
@extend %button-reset;
color: white;
background: #blue;
}
.delete {
@extend %button-reset;
color: white;
background: red;
}
%button-reset就是那個虛假的占位選擇器,HTML中從不會用它,它只用于scss文件中。然后,@extend %button-reset表示把.save、.delete這些個class名字,復制到%button-reset的位置上,形成:
.save, .delete {
margin: 0;
padding: .5em 1.2em;
text-decoration: none;
cursor: pointer;
}
.save {
color: white;
background: #blue;
}
.delete {
color: white;
background: red;
}
使用占位選擇器和繼承,你應該注意這幾點:
- 優先繼承占位選擇器,而不是繼承具體的選擇器;
- 如果必須繼承一個 .class 時,請只繼承單一的 .class,不要使用復雜的選擇器;
- 繼承能不用就不用,畢竟繼承比嵌套更復雜,你需要在代碼簡化與直觀上做權衡;
- 避免繼承常見的父類選擇器(比如: .foo .bar)或者是常見的相鄰選擇器(比如:.foo ~ .bar),否則會讓選擇器的數量急速增加。
- 不要跨媒體查詢繼承。
跟@mixin+@include作對比:
繼承跟@mixin+@include有一點像,但作用相反:
- @mixin+@include是把一段代碼分發給N處;
- %+@extend是把N處的選擇符匯總起來寫成組合選擇符,給這個組合選擇符再配上聲明;
- 如果只有@extend沒有%,是把N處的class名字匯總起來加到一個已有的選擇器的后面并列起來。
那么哪些情況用混合器,哪些情況用繼承?
混合器主要用于展示性樣式的重用,而類名用于語義化樣式的重用。因為繼承主要是基于類的(也有時是基于其他類型的選擇器),所以繼承應該是建立在語義化的關系上。當一個元素擁有的類(比如說.seriousError)表明它屬于另一個類(比如說.error) ,這時使用繼承再合適不過了。
也就是說:
- 當你想復用一些表現上的高使用率的代碼時,你應該用混合器;
- 當你想復用邏輯上的更宏觀的類的時候,應該用繼承;
- 混合器的名稱只在scss內有效;
- 繼承的類名或者其他選擇符,都是HTML文件中真實存在的名稱。
- 跟混合器相比,繼承生成的CSS代碼相對更少。因為繼承僅僅是重復選擇器,而不會重復聲明,所以使用繼承往往比混合器生成的CSS體積更小。如果你非常關心你站點的速度,請牢記這一點。
- 繼承遵從CSS層疊的規則。當兩個不同的CSS規則應用到同一個HTML元素上時,并且這兩個不同的CSS規則對同一屬性的修飾存在不同的值, CSS層疊規則會決定應用哪個樣式。相當直觀:通常權重更高的選擇器勝出,如果權重相同,定義在后邊的規則勝出。
進階:使用繼承的最佳實踐
就一句話:不要讓后代選擇器(比如.foo .bar)去繼承CSS規則。但你完全可以放心地繼承有后代選擇器修飾規則的選擇器,不管后代選擇器多長。也就是說:
絕對不要:
.foo .bar {
@extend #id;
}
允許:
.foo {
@extend #id .bar .a .b .c .d;
}
所以,如果你想讓.seriousError繼承.error,不要給.seriousError的前面加父選擇符。
流程控制
條件語句
@if可以用來判斷:
p {
@if 1 + 1 == 2 {
border: 1px solid; }
@if 5 < 3 {
border: 2px dotted; }
}
配套的還有@else命令:
@if lightness($color) > 30% {
background-color: #000;
} @else {
background-color: #fff;
}