使用 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 內隨手引用。
 
 
沒有留言:
張貼留言