淺談OOCSS、SMACSS、BEM三種設計模式與前端架構優化的關係

佀無極發表於2018-09-27

淺談OOCSS、SMACSS、BEM三種設計模式與前端架構優化的關係

物件導向的OOCSS,是由Nicole Sullivan提出的css理論,雖說是理論,實則更像一種程式設計師約定的規範。
<div class=”demo-list”>
    <ul>
        <li><a href=”#”>…</a></li>
        <li><a href=”#”>…</a></li>
        <li><a href=”#”>…</a></li>
    </ul>
</div>
對a修改樣式可能用.demo-list ul li a選擇,效率比較低,另一方面一旦在後期過程中對列表html進行重構,css也需要重構,耦合性變得很強,維護困難。
OOCSS推薦的寫法是在a標籤加上demo-a樣式,可以通過.demo-list .demo-a的方式來控制解耦。
提取公共樣式很多框架都是這種模式,Bootstrap按鈕.btn-info、.btn-warning等。

 

SMACSS通過一個靈活的思維過程來檢查你的設計過程和方式是否符合你的架構,更像一種規範~
    1為css分類
    2命名規範
    3最小化適配深度

1為css分類
為css分類這一點是SMACSS的核心。SMACSS認為css有5個類別,分別是: 
1 Base 
2 Layout 
3 Module 
4 State 
5 Theme or Skin
SMACSS還約定了一個字首l-/layout-來標識佈局的class
.layout-header {}
.layout-container {}
.layout-sidebar {}
.layout-content {}
.layout-footer {}
SMACSS中的模組具有自己的一個命名,隸屬於模組下的類皆以該模組為字首
.todolist{}
.todolist-title{}
.todolist-image{}
.todolist-article{}
SMACSS狀態規範,這個應該很多前端開發者都很好理解,描述的是任一元素在特定狀態下的外觀。
is-hidden
主題規範,描述了頁面主題外觀,一般是指顏色、背景圖。Theme Rules可以修改前面4個類別的樣式,且應和前面4個類別分離開來(便於切換,也就是“換膚”)。SMACSS的Theme Rules不要求使用單獨的class命名,也就是說,你可以在Module Rules中定義.header{ }然後在Theme Rules中也用.header { }來定義需要修改的部分(後載入覆蓋前載入樣式內容)

2命名規範
按照前面5種的劃分:
Base Rules(Pass)
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。

3最小適配深度
/* depth 1 */ .sidebar ul h3 { }
/* depth 2 */ .sub-title { }
兩段css的區別在於html和css的耦合度(這一點上和OOCSS的分離容器和內容的原則不謀而合)。可以想到,由於上面的樣式規則使用了繼承選擇符,因此對於html的結構實際是有一定依賴的。如果html發生重構,就有可能不再具有這些樣式。對應的,下面的樣式規則只有一個選擇符,因此不依賴於特定html結構,只要為元素新增class,就可以獲得對應樣式。
當然,繼承選擇符是有用的,它可以減少因相同命名引發的樣式衝突(常發生於多人協作開發)。但是,我們不應過度使用,在不造成樣式衝突的允許範圍之內,儘可能使用短的、不限定html結構的選擇符。這就是SMACSS的最小化適配深度的意義。

 

BEM,即Block,Element,Modifier,是由Yandex(俄羅斯最著名的網際網路企業)的開發團隊提出的前端開發理論。BEM通過Block、Element、Modifier來描述頁面(關鍵就是為了解決多人協作的命名問題)。
Block是頁面中獨立存在的區塊,可以在不同場合下被重用。每個頁面都可以看做是多個Block組成。
Modifier是描述Block或Element的屬性或狀態。同一Block或Element可以有多個Modifier。
在用 jQuery 可以常常看到這樣的寫法:$(‘.nav–main a’),一旦css發生重構,javascript程式碼也將變得難以維護,分不清那些程式碼是否會受到影響。
所以用 HTML 的屬性去選取 DOM 節點會更好,如果非要用 CSS 的 class 那也可以多寫一個 js- 的 prefix,以表示這個節點有被 Javascript 使用,例如:
<li><a class=`nav-a js-nav-a`></a></li>
<li><a class=`nav-a js-nav-a`></a></li>
<li><a class=`nav-a js-nav-a`></a></li>

 

三種設計模式都有共同的特點,那便是讓html與css更好的解耦,抽取樣式中可複用的部分,使你的html程式碼更具語義。瞭解這些設計模式無疑會使css程式碼更具模組化,多人協作的時候也能有效避免那些命名問題帶來的困擾又或者說提供一些解決的思路。最重要是提取精華,靈活應用,更加的規範規模化,在達到提高效率的同時兼顧效能。


相關文章