使用 SCSS 工作時的筆記。用點力統整、擴寫一下,內容已經有點太長,囧。
@extend 與 %style
官方文件 https://sass-lang.com/documentation/at-rules/extend功能:引用對象 .classB 與既有樣式 .classA (此稱拓展對象) 共用 classA 的樣式,形成 .classA, .classB{...(classA的css宣告)...} 這般的grouping selector;此語法拓展 grouping selectors 的應用彈性。基礎用法請參照官方範例,筆記內文沒有著墨。
- 拓展對象需比引用對象提前宣告,以方便後者引用
- class name 不能複數引用
- 根據官網所言,若 selector .A.B{...} 存在,可成功將 style 拓展到 .A.B 之對應樣式
@extend .A.B;
- class name 是可以加變數的。但記得 mixin name 中則不行加變數的樣子。
@extend .style-#{$var};
- %style{...} 不會被編譯,但可被@extend 引用
@extend %style;
- bootstrap框架使用者注意:
@media require 等同於 @include media-breakpoint-*() in
bootstrap。media-breakpoint-*() 內混用 @extend 時也要一併考量下文提到的狀況, SCSS
比較能順利編譯成功。
- 步驟一:先檢查引用對象 .classB 是否存在 media require
- 步驟二:再對比拓展對象 .classA 是否與引用對象 .classB 擁有相同 media require ,若兩者 @media 條件式不同,則會導致編譯失敗。
.classA{
background:pink;
}
@media (min-width:576px){
.classB{
border-color:gray;
@extend .classA; // 無法成功編譯
}
}
@extend .classA
本質上的功能是將引用對象 .classB
加個逗點掛在 .classA
後面,變成 grouping selects,成為 .classA, .classB{...(classA的css宣告)..}
。但在使用 @media
時,media require 將優先於 class 宣告,因此 .classB{ ... }
外面會包覆一層 media require,形成 @media (...){ .classB{...}}
。多了一層包覆結構的 @media (...){ .classB{...}}
,難以和 .classA 形成合法的 grouping selects 。例如 .classA,@media (...){ .classB}{...(classA的css宣告)..}
是一個不合法的選擇器(selector),因此 SCSS 編譯器會提前檢查出錯誤並阻擋之後的編譯過程。.classA,
@media (min-width:576px){.classB}{ //不合法的selector
background:pink;
}
- 宣告一個和 .classB 之 media require 條件相同的 .classA
- 直接替拓展對象 .classA 包覆條件一樣的 media require。
但此舉需注意其他有 extend .classA 的 class 是否也符合相同media require,否則依然導致編譯失敗 - 複製一份 .classA 再將它包覆條件一樣的 media require。
- 將拓展對象 .classA 重新在 包含有目的 .classB 的 media require 裡再宣告一次(一樣是再複製一次的概念)
- 直接替拓展對象 .classA 包覆條件一樣的 media require。
- 把 .classA 內部 css 屬性取出命名為新mixin,即能以引用mixin的方式,無視 media require 隨意引用在各種class的肚子裡
.classA{
background:pink;
}
@media (min-width:576px){
.classA-1-2 { // 方法1.2;
color:green;
}
}
@media (min-width:576px){
.classA-1-3{ // 方法1.3
margin:1rem;
}
.classB{
border-color:gray;
@extend .classA-1-2;
@extend .classA-1-3;
}
}
.classB-in-bootstrap{ // 將示範目標改寫為 bootstrap 常見寫法
border-color:gray;
@include media-breakpoint-up(sm){
//@extend .classA; // 依然無法成功編譯
@extend .classA-1-2;
@extend .classA-1-3;
}
}
方法2. mixin作法範例,等mixin的相關筆記補完後再寫。
@media (min-width:576px){
.classC{
font-size:3rem;
}
}
.classD{
@extend .classC; // 可以成功編譯
}
先前提過,因為編譯時會先檢查「步驟一:引用對象是否具有 media require」再進行其後步驟。既然引用對象沒有 media require,就不需再往下檢查其他錯誤可能,直接編譯成功。為何這樣可以行得通的原因,一樣要回歸 @extend 的原始原理:引用對象 .classD 易與拓展對象 @media (...){.classC{...}}
形成 grouping selectors,即:
@media (...){
.classC, .classD{
...
}
}
延伸:bootstrap 框架已先備許多 breakpiont classes,就很適合在 bootstrap 後的客製化 css/scss 內隨手引用。
沒有留言:
張貼留言