iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0
Modern Web

CSS 實戰心法系列 第 26

實戰心法 - 應避免的 Sass @extend

Sass 的 @extend 可以將相同的樣式整理再一起,在其他語言來說是非常帥氣的技法,但在 CSS 中請警慎使用。

就如同本篇鐵人賽一開始所介紹到的 OOCSS 概念,在撰寫 CSS 時要盡可能符合兩個原則,結構與樣式分離、容器與內容分離,所以到這邊為止還是要貫徹這個概念,當使用 @extend 時如果會造成這個缺陷時,請避免使用。

帥氣的 @extend

@extend 能夠將重複的樣式整理再一起,以下面的範例來說,我就將 .clearfix.row 中所需要的清除浮動做整理。

編譯前:

%clearfix {
  &:after {
    content: " ";
    display: table;
    clear: both;
  }
}

.clearfix {
  @extend %clearfix;
}

.row {
  @extend %clearfix;
}

編譯後:

.clearfix:after, .row:after {
  content: " ";
  display: table;
  clear: both;
}

{% raw %}

這手法可以有效減少散落在各處的樣式,無論他在第幾行,都會被往前統一整理。

錯誤的案例

本篇繼續上一篇的範例,上一篇中我們是將 .btn 作為獨立的 Class,且此 Class 身負作為按鈕結構的重任。

在 Sass 中,我們會先新增一個 %btn 來作為 placeholder selectors,而後再 Class 的部分透過 @extend%btn 合併,那麼結構的部分也會合併到每一個按鈕內。

%btn {
  // 結構
  display: inline-block;
  padding: 6px 12px;
  margin-bottom: 0;
  font-size: 14px;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  background-image: none;
  border: 1px solid transparent;
  border-radius: 4px;
  &:hover, &:focus {
    color: #333;
    background-color: #e6e6e6;
  }
}

@each $name, $value in $btn-config {
  $class: map-get($value, class);
  $color: map-get($value, color);
  $bg: map-get($value, bg);
  $border-color: map-get($value, border-color);

  .btn-#{$class}{
    @extend %btn;
    @include button-variant($color, $bg, $border-color);
  }
}

此作法 HTML 會看起來相當簡潔。

<div class="section">
  <button class="btn-default">這是一個按鈕</button>
  <button class="btn-primary">這是一個按鈕</button>
  <button class="btn-accent">這是一個按鈕</button>
</div>

範例:http://codepen.io/Wcc723/pen/JbqZOJ/

雖然說,這樣的在寫的時候看似非常簡潔,但其實所產出的 CSS 檔案非常之肥大,所有樣式結構的 Class 會被拉到前面在寫再一起,無形之中會重複大量的 Class name,如以下所產出的 disabled 的樣式。

.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active {
  background-color: #009AFF;
  border-color: #009AFF;
}

結語

其實學到現在,要安全點其實是避開 @extend 不使用,就連 Bootstrap 的原始碼中也不怎麼使用 @extend 這手法,但為什麼本篇會特別提出呢...!?因為我以前就是敗在這上的啊 Q_Q。

文章同時發表於:https://wcc723.github.io/css/2016/12/26/sass-extend/


上一篇
實戰心法 - Sass Map 快出產出大量樣式
下一篇
CSS 框架自幹心得 - 失敗三次的框架建構經驗
系列文
CSS 實戰心法30

尚未有邦友留言

立即登入留言