值得參考的css理論:OOCSS、SMACSS與BEM

最近在The Sass Way[]一文,發現文章在開頭部分就提到了OOCSSSMACSSBEM、這3個詞。「若是還不知道這些是什麼,請先不要繼續看下去」,聯想到做者這樣友好(gāo lěng)的提醒,做爲圍觀羣衆,天然要有所迴應。因此,本文在這裏分別介紹它們。javascript

OOCSS、SMACSS及BEM都是有關css的方法論(準確地說,其中BEM應該是一個完整的前端開發理論,不只限於css),可做爲實現優秀css架構(css architecture)的指南。css

css易於理解,但應用和維護並不簡單。在各類開發情景下,css均可能成爲一個問題點。所以,咱們編寫和組織css應認真、用心。html

OOCSS

[OOCSS][]Object Oriented CSS),字面意思是面向對象的CSS,是由Nicole Sullivan提出的css理論,其主要的兩個原則是:前端

  • Separate structure and skin(分離結構和主題)java

  • Separate container and content(分離容器和內容)sass

用一個例子來講明。請看下面這樣的圖文排列:架構

oocss示例

<div class="media media-shadow">
    <div class="media-image-container">
        <img class="media-image" src="rean.jpg" alt="">
    </div>
    <div class="media-body">
        <p class="media-text">本做的主角,帝國北部地方貴族施瓦澤男爵的養子,也是托爾茲士官學校特科班「Ⅶ組」的成員。</p>
    </div>
</div>

----less

.media{
    padding: 10px;
}
.media:after{
    display: table;
    clear: both;
    content: " ";
}
.media-image-container{
    float: left;
    margin-right: 10px;
}
.media-image{
    display: block;
}
.media-body{
    overflow: hidden;
}
.media-shadow{
    box-shadow: 1px 1px 3px rgba(0, 0, 0, .5);
}

上面這段代碼用media表示了這種圖文排列的頁面元素。若是把構成它的html、css及javascript(若是有)看作一個總體,那就至關於這是一個元件,或者說對象(object)。它能夠在站點的任何地方被重用。ide

這樣是如何體現OOCSS的兩個原則的呢?佈局

Separate structure and skin

分離結構和主題是在於將一些視覺樣式效果(例如backgroundcolor)做爲單獨的「主題」來應用。在上面的例子中的陰影效果,沒有被直接寫在media的樣式規則內,而是被單獨寫在了一個名爲media-shadow的class中。所以,它成爲了可選擇、可拆分的主題。若是不須要對應主題,什麼也不要加,若是須要,加上對應的class,就是這樣的思路。

Separate container and content

分離容器和內容要求使頁面元素不依賴於其所處位置。在上面的例子中,css的選擇符都很短,無繼承選擇符(例如.header .media { }),因此,這個圖文排列的元件,能夠在任何地方使用,且會有一致的外觀。

若是須要在特定的地方讓這個元件看起來不同一些,繼續爲這個元件增長class,將「不同的部分」做爲可配置的選項。元件的外觀仍不依賴其所處位置。

操做指南

能夠看出,OOCSS風格的css能夠描述爲兩點:

  • 增長class

  • 不使用繼承選擇符

OOCSS追求元件的複用,其class命名比較抽象,通常不體現具體內容。

SMACSS

**SMACSS[]提出的css理論。其主要原則有3條:

  • Categorizing CSS Rules(爲css分類)

  • Naming Rules(命名規則)

  • Minimizing the Depth of Applicability(最小化適配深度)

這些原則分別是什麼意思呢?

Categorizing CSS Rules

這一點是SMACSS的核心。SMACSS認爲css有5個類別,分別是:

  1. Base

  2. Layout(Major Components)

  3. Module(Minor Components)

  4. State

  5. Theme

Base Rules基礎樣式,描述的是任何場合下,頁面元素的默認外觀。它的定義不會用到class和ID。css reset也屬於此類。

Layout Rules佈局樣式。它和後面的Module Rules一同,描述的是頁面中的各種具體元素。元素是有層次級別之分的,Layout Rules屬於較高的一層,它能夠做爲層級較低的Module Rules元素的容器。左右分欄、柵格系統等都屬於佈局樣式。

Module Rules模塊樣式。它能夠是一個產品列表,一個導航條。通常來講,Module Rules定義的元素放置於前面說的Layout Rules元素以內。模塊是獨立的,能夠在各類場合重用。

State Rules狀態樣式,描述的是任一元素在特定狀態下的外觀。例如,一個消息框可能有successerror兩種狀態,導航條中的任一項均可能有current狀態。

繼續OOCSS中的例子,下面新增的讓元素不顯示的is-hidden就屬於State Rules:

<div class="media media-shadow is-hidden">
    ...
</div>

.is-hidden{
    display: none;
}

Theme Rules主題樣式,描述了頁面主題外觀,通常是指顏色、背景圖。Theme Rules能夠修改前面4個類別的樣式,且應和前面4個類別分離開來(便於切換,也就是「換膚」)。SMACSS的Theme Rules不要求使用單獨的class命名,也就是說,你能夠在Module Rules中定義.mod { }而後在Theme Rules中也用.mod { }來定義須要修改的部分。

Naming Rules

Naming Rules是說在想class等的命名時,考慮用命名體現樣式對應的類別。

按照前面5種的劃分,Layout Rules用l-layout-這樣的前綴,例如:.l-header.l-sidebar

Module Rules用模塊自己的命名,例如圖文排列的.media.media-image

State Rules用is-前綴,例如:.is-active.is-hidden

Theme Rules若是做爲單獨class,用theme-前綴,例如.theme-a-background.theme-a-shadow

Base Rules不會用到class和ID,是以標籤選擇符爲主的樣式,例如pa,無需命名。

命名規則不須要嚴格遵照,能夠根據實際狀況和自身喜愛作其餘的約定。記錄本身的約定(寫文檔),而後遵照,就是可行的。

Minimizing the Depth of Applicability

字面翻譯是最小化適配深度。經過一個簡單的描述來講明:

/* depth 1 */
.sidebar ul h3 { }

/* depth 2 */
.sub-title { }

上下兩端css的區別在於html和css的耦合度。能夠想到,因爲上面的樣式規則使用了繼承選擇符,所以對於html的結構實際是有必定依賴的。若是把h3元素搬到另外一個位置,就有可能再也不具備這些樣式。對應的,下面的樣式規則只有一個選擇符,所以不依賴於特定html結構,只要爲元素添加class,就能夠得到對應樣式。

固然,繼承選擇符是有用的,它能夠減小因相同命名引起的樣式衝突(常發生於多人協做開發)。可是,咱們不該過分使用,在不形成樣式衝突的容許範圍以內,儘量使用短的、不限定html結構的選擇符。這就是SMACSS的最小化適配深度的意義。

看起來,這一點和OOCSS的分離容器和內容的原則很是類似。

主要目標

SMACSS着力於實現兩個主要目標:

  • 更語義化的html和css

  • 下降對特定html結構的依賴

BEM

**BEM[](俄羅斯最著名的互聯網企業)的開發團隊提出的前端開發理論。BEM經過Block、Element、Modifier來描述頁面。

Block是頁面中獨立存在的區塊,能夠在不一樣場合下被重用。每一個頁面均可以看作是多個Block組成。

BEM-Block

Element是構成Block的元素,只有在對應Block內部才具備意義,是依賴於Block的存在。

BEM-Element

Modifier是描述Block或Element的屬性或狀態。同一Block或Element能夠有多個Modifier。

這三部分結合在一塊兒,能夠體如今class命名上,從而爲開發者提供更友好、更有意義的css組織方式。其形式是:

.block { }
.block_modifier { }
.block__element { }
.block__element_modifier { }

再回到前面OOCSS的那個圖文排列的例子,對應用BEM的寫法的話就是:

<div class="media media_shadow">
    <div class="media__image-container">
        <img class="media__image" src="rean.jpg" alt="">
    </div>
    <div class="media__body">
        <p class="media__text">本做的主角,帝國北部地方貴族施瓦澤男爵的養子,也是托爾茲士官學校特科班「Ⅶ組」的成員。</p>
    </div>
</div>

這樣的寫法的好處是,在class命名上以約定的形式攜帶了更多有用信息。在多人合做的時候,新接手這個項目的人,也能夠很容易從class命名上分辨出來,哪些部分是Block,哪些是對應的Element,哪些是Modifier,並進一步推斷出哪部分html能夠獨立使用。

BEM是完整的前端開發理論,這裏只是提到了它採用的css的class命名規則。能夠看出,BEM的命名規則可使代碼更易於維護。

綜合結論

這些理論真的能夠應用嗎?

是的,並且有用。可是,請不要過於樂觀,任一種理論都只是對解決css編寫、維護問題的一種嘗試,及其經驗總結。就實際具體的項目來講,你可能仍然會遇到困惑。這些理論最重要的是提供了一種思路(即便它們也提供開發模式的代碼庫),你可能不直接應用它們,但應該經過它們認識到,在寫代碼以前,須要多一些思考。

不直接編寫css而是採用less、sass等預編譯器,也一樣須要合理的代碼編寫和組織方式,由於能夠從編譯後獲得的css來分析,因此原則是相通的。

結語

在整理寫文本以前,我只初步瞭解過OOCSS,而對另外2個尚未印象...(嗯,其實很正常)

本文的3個理論各有各的風格,沒有孰優孰劣之說,都是在編寫css時值得參考的內容。若是能夠,很是推薦本身根據這些理論背後的意圖,想一個適合本身的方法。

(從新編輯自個人博客,原文地址:http://acgtofe.com/posts/2014/09/valuable-theories-of-css

相關文章
相關標籤/搜索