Airbnb CSS / Sass 指南

用更合理的方式寫 CSS 和 Sass

原文出自 Airbnb CSS / Sass Styleguide

譯文 GitHub 鏈接,歡迎各位指正。

目錄

  1. 術語
    • 規則聲明
    • 選擇器
    • 屬性
  2. CSS
    • 格式
    • 注釋
    • OOCSS 和 BEM
    • ID 選擇器
    • JavaScript 鉤子
    • 邊框
  3. Sass
    • 語法
    • 排序
    • 變數
    • Mixins
    • 擴展指令
    • 嵌套選擇器

術語

規則聲明

我們把一個(或一組)選擇器和一組屬性稱之為 「規則聲明」。舉個例子:

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

選擇器

在規則聲明中,「選擇器」 負責選取 DOM 樹中的元素,這些元素將被定義的屬性所修飾。選擇器可以匹配 HTML 元素,也可以匹配一個元素的類名、ID, 或者元素擁有的屬性。以下是選擇器的例子:

.my-element-class { /* ... */}[aria-hidden] { /* ... */}

屬性

最後,屬性決定了規則聲明裡被選擇的元素將得到何種樣式。屬性以鍵值對形式存在,一個規則聲明可以包含一或多個屬性定義。以下是屬性定義的例子:

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

CSS

格式

  • 使用 2 個空格作為縮進。
  • 類名建議使用破折號代替駝峰法。如果你使用 BEM,也可以使用下劃線(參見下面的OOCSS 和 BEM)。
  • 不要使用 ID 選擇器。
  • 在一個規則聲明中應用了多個選擇器時,每個選擇器獨佔一行。
  • 在規則聲明的左大括弧 { 前加上一個空格。
  • 在屬性的冒號 : 後面加上一個空格,前面不加空格。
  • 規則聲明的右大括弧 } 獨佔一行。
  • 規則聲明之間用空行分隔開。

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 { // ...}

注釋

  • 建議使用行注釋 (在 Sass 中是 //) 代替塊注釋。
  • 建議注釋獨佔一行。避免行末注釋。
  • 給沒有自注釋的代碼寫上詳細說明,比如:
    • 為什麼用到了 z-index
    • 兼容性處理或者針對特定瀏覽器的 hack

OOCSS 和 BEM

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

  • 可以幫助我們理清 CSS 和 HTML 之間清晰且嚴謹的關係。
  • 可以幫助我們創建出可重用、易裝配的組件。
  • 可以減少嵌套,降低特定性。
  • 可以幫助我們創建出可擴展的樣式表。

OOCSS,也就是 「Object Oriented CSS(面向對象的CSS)」,是一種寫 CSS 的方法,其思想就是鼓勵你把樣式表看作「對象」的集合:創建可重用性、可重複性的代碼段讓你可以在整個網站中多次使用。

參考資料:

  • Nicole Sullivan 的 OOCSS wiki
  • Smashing Magazine 的 Introduction to OOCSS

BEM,也就是 「Block-Element-Modifier」,是一種用於 HTML 和 CSS 類名的命名約定。BEM 最初是由 Yandex 提出的,要知道他們擁有巨大的代碼庫和可伸縮性,BEM 就是為此而生的,並且可以作為一套遵循 OOCSS 的參考指導規範。

  • CSS Trick 的 BEM 101
  • Harry Roberts 的 introduction to BEM

示例

<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 { }

  • .listing-card 是一個塊(block),表示高層次的組件。
  • .listing-card__title 是一個元素(element),它屬於 .listing-card 的一部分,因此塊是由元素組成的。
  • .listing-card--featured 是一個修飾符(modifier),表示這個塊與 .listing-card有著不同的狀態或者變化。

ID 選擇器

在 CSS 中,雖然可以通過 ID 選擇元素,但大家通常都會把這種方式列為反面教材。ID 選擇器給你的規則聲明帶來了不必要的高優先順序,而且 ID 選擇器是不可重用的。

想要了解關於這個主題的更多內容,參見 CSS Wizardry 的文章,文章中有關於如何處理優先順序的內容。

JavaScript 鉤子

避免在 CSS 和 JavaScript 中綁定相同的類。否則開發者在重構時通常會出現以下情況:輕則浪費時間在對照查找每個要改變的類,重則因為害怕破壞功能而不敢作出更改。

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

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

邊框

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

Bad

.foo { border: none;}

Good

.foo { border: 0;}

Sass

語法

  • 使用 .scss 的語法,不使用 .sass 原本的語法。
  • CSS 和 @include 聲明按照以下邏輯排序(參見下文)

屬性聲明的排序

  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; }}

變數

變數名應使用破折號(例如 $my-variable)代替 camelCased 和 snake_cased 風格。對於僅用在當前文件的變數,可以在變數名之前添加下劃線前綴(例如 $_my-variable)。

Mixins

為了讓代碼遵循 DRY 原則(Don』t Repeat Yourself)、增強清晰性或抽象化複雜性,應該使用 mixin,這與那些命名良好的函數的作用是異曲同工的。雖然 mixin 可以不接收參數,但要注意,假如你不壓縮負載(比如通過 gzip),這樣會導致最終的樣式包含不必要的代碼重複。

擴展指令

應避免使用 @extend 指令,因為它並不直觀,而且具有潛在風險,特別是用在嵌套選擇器的時候。即便是在頂層佔位符選擇器使用擴展,如果選擇器的順序最終會改變,也可能會導致問題。(比如,如果它們存在於其他文件,而載入順序發生了變化)。其實,使用 @extend 所獲得的大部分優化效果,gzip 壓縮已經幫助你做到了,因此你只需要通過 mixin 讓樣式表更符合 DRY 原則就足夠了。

嵌套選擇器

請不要讓嵌套選擇器的深度超過 3 層!

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

當遇到以上情況的時候,你也許是這樣寫 CSS 的:

  • 與 HTML 強耦合的(也是脆弱的)—或者—
  • 過於具體(強大)—或者—
  • 沒有重用

再說一遍: 永遠不要嵌套 ID 選擇器!

如果你始終堅持要使用 ID 選擇器(勸你三思),那也不應該嵌套它們。如果你正打算這麼做,你需要先重新檢查你的標籤,或者指明原因。如果你想要寫出風格良好的 HTML 和 CSS,你是應該這樣做的。

歡迎關注

  • 新浪微博:前端外刊評論

  • 博客:前端外刊評論
  • 順便宣傳一下寧 JS,感興趣的朋友請戳 NingJS - JSConf China 2016


推薦閱讀:

名人堂 | W3CPlus中國創始人大漠:前端路上的旅行
CSS布局十八般武藝都在這裡了
經驗 | 張鑫旭對知乎前端相關問題的十問十答
了解 Twitter 前端架構 學習複雜場景數據設計
前端入門第五彈:初探前端職場

TAG:前端开发 | CSS | 前端工程师 |