Home

Awesome

Airbnb CSS / Sass 指南

用更合理的方式寫 CSS 和 Sass

翻譯自 Airbnb CSS / Sass Styleguide

目錄

  1. 術語 - 規則宣告 - 選擇器 - 屬性
  2. CSS - 格式 - 註解 - OOCSS 和 BEM - ID 選擇器 - JavaScript 掛鉤 - 邊框
  3. Sass - 語法 - 排序 - 變數 - Mixins - 擴展指令 - 巢狀選擇器

<a name="terminology"></a>

術語

<a name="rule-declaration"></a>

規則宣告

我們把包含一組屬性的一個(或多個組合的)選擇器稱之為 “規則宣告”。舉個例子:

.listing {
  font-size: 18px;
  line-height: 1.2;
}

<a name="selectors"></a>

選擇器

在規則宣告中,“選擇器” 決定了 DOM 樹中的哪些元素將被定義的屬性所修飾。選擇器可以配對 HTML 元素,也可以配對一个元素的類別名稱、ID, 或者元素擁有的屬性。以下是選擇器的例子:

.my-element-class {
  /* ... */
}

[aria-hidden] {
  /* ... */
}

<a name="properties"></a>

屬性

最後,屬性決定了規則宣告裡面被選擇的元素將會得到何種樣式。屬性以 key-value pairs 形式存在,一個規則宣告可以包含一或多個屬性宣告。屬性宣告如下:

/* some selector */ {
  background: #f1f1f1;
  color: #333;
}

<a name="css"></a>

CSS

<a name="formatting"></a>

格式

Bad

.avatar{
    border-radius:50%;
    border:2px solid white; }
.no, .nope, .not_good {
    // ...
}
#lol-no {
  // ...
}

Good

.avatar {
  border-radius: 50%;
  border: 2px solid white;
}

.one,
.selector,
.per-line {
  // ...
}

<a name="comments"></a>

註解

<a name="oocss-and-bem"></a>

OOCSS 和 BEM

由於以下原因,我們鼓勵使用 OOCSS 和 BEM 的某些組合:

OOCSS,也就是 “Object Oriented CSS(物件導向的CSS)”,是一種寫 CSS 的方法,中心哲學就是鼓勵你把樣式表看成“物件”的集合:利用擁有可重用、可重組特性的程式碼,使你可以在整個網站中多次使用。

参考資料:

BEM,也就是 “Block-Element-Modifier”,是一種用於 HTML 和 CSS 類別名稱的_命名约定_。BEM 最初由 Yandex 所提出,他們擁有大量的程式庫以及延展性。可以作為一套遵循 OOCSS 的實作參考規範。

建議使用搭配 PascalCased "區塊"的變形 BEM,在與元件結合操作時特別適用 (e.g. React)。底線與破折號依然用在修飾符與子元件。

範例

<article class="listing-card listing-card--featured">

  <h1 class="listing-card__title">Adorable 2BR in the sunny Mission</h1>

  <div class="listing-card__content">
    <p>Vestibulum id ligula porta felis euismod semper.</p>
  </div>

</article>
.listing-card { }
.listing-card--featured { }
.listing-card__title { }
.listing-card__content { }

<a name="id-selectors"></a>

ID 選擇器

雖然在 CSS 中,你可以透過 ID 選擇元素,但這種作法應該列為 anti-pattern。ID 選擇器為你的規則宣告帶來了不必要的高優先權級,而且 ID 選擇器不可重用。

想要了解更多關於這個主題的內容,請參考 CSS Wizardry 的文章,內有關於如何處理優先權級的文章。

<a name="javascript-hooks"></a>

JavaScript 掛鉤

避免在 CSS 和 Javascript 中綁定相同的類別。否則開發者在進行重構時容易出現問題,輕則浪費時間在相互對照尋找要修改的類別名稱,嚴重則因為害怕破壞功能而不敢進行更動。

我們推薦在創建用於 JavaScript 的類別名稱時,添加 .js- 前綴:

<button class="btn btn-primary js-request-to-book">Request to Book</button>

<a name="border"></a>

邊框

在定義無邊框樣式時,使用 0 代替 none

Bad

.foo {
  border: none;
}

Good

.foo {
  border: 0;
}

<a name="sass"></a>

Sass

<a name="syntax"></a>

語法

<a name="ordering-of-property-declarations"></a>

屬性宣告的排序

  1. 屬性宣告

    列出除了 @include 與 巢狀選擇器之外的所有屬性宣告。

    .btn-green {
      background: green;
      font-weight: bold;
      // ...
    }
    
  2. @include 宣告

    接著再放入 @include,這樣可以提高整個選擇器的可讀性。

    .btn-green {
      background: green;
      font-weight: bold;
      @include transition(background 0.5s ease);
      // ...
    }
    
  3. 巢狀選擇器

    _如果有必要_用到巢狀選擇器,把它們放到最後。此外,規則宣告與巢狀選擇器之間要加上空白行。而巢狀選擇器中的內容也要遵循上述指引。

    .btn {
      background: green;
      font-weight: bold;
      @include transition(background 0.5s ease);
    
      .icon {
        margin-right: 10px;
      }
    }
    

<a name="variables"></a>

變數

變數名稱建議使用破折號(例如 $my-variable)代替 camelCased 和 snake_cased 風格。可以在變數名稱之前添加底線前綴符,用以代表此變數只使用於當前文件。(例如 $_my-variable)。

<a name="mixins"></a>

Mixins

Mixins 可幫助你的代碼遵循 DRY 原則(Don't Repeat Yourself)、增加清晰度或抽象畫複雜度。這與使用良好命名的函數有異曲同工之妙。Mixins 可以不接收參數,但要注意的是,如果你不壓縮 payload(e.g. gzip),可能會導致最終的樣式表包含不必要的重複程式碼。

<a name="extend-directive"></a>

擴展指令

應避免使用 @extend 指令,因為他並不直觀,且具有潛在風險,特別是用在巢狀選擇器時。即使是針對在最上層的佔位符選擇器使用擴展,如果選擇器的順序最終會改變,也可能會導致問題。(比如,擴展的選擇器存在於別份文件,而其加載順序發生變化)。使用 @extend 所獲得的大部分優化效果,透過 gzip 縮就已經幫你做到了,而你可以再透過 mixin 來讓你的樣式表更符合 DRY 原則。

<a name="nested-selectors"></a>

巢狀選擇器

請不要讓巢狀選擇器超過三層!

.page-container {
  .content {
    .profile {
      // STOP!
    }
  }
}

當上述情況發生時,你也許是這樣寫 CSS 的:

再說一遍: 永遠不要巢狀 ID 選擇器!

如果你真的必須使用 ID 選擇器(你真的不應該...),那他們也不該是巢狀的。如果你發現你正在這樣做,那你可能需要重新檢查你的 markup,或是說明這樣做的原因。如果你想要寫出良好風格的 HTML 和 CSS,你絕對應該這麼做。

翻譯

這份 style guide 也被翻譯成以下語言: