
















我們平時最開始學習寫 CSS 代碼的時候,我們都是這麼寫的:
.main-part .tabs {
/*...*/
}
其實這樣的寫法是不好的,因為它過度的與頁面中的某一部分耦合了。我們在軟件工程的思想中追求的就是解耦。
BEM 的命名規範不是死的,可以參考 bem-conventions
這裡有一些可供選擇的基於 BEM 命名約定的方案。
block-name__elem-name--mod-name
MyBlock__SomeElem_modName_modVla
這種風格的命名方案的不同點在於,在 BEM 實體中分隔單詞時使用駝峰命名法代替了一個連字符(-)。
blockName-elemName--modName--modVal
名稱使用駝峰命名法書寫。 元素名稱與模塊名稱使用一個連字符(-)分隔。 修飾符使用雙連字符(–)與模塊或元素分隔, 修飾符的名稱和值使用雙連字符(–)分隔。 重要提示!
在注釋中,雙連字符被視為注釋的一部分,因此在文檔驗證時,雙破折號可能會引起錯誤。HTML5 Specification
在這邊使用 BEM 的命名規範,每行 CSS 代碼都只有一個選擇器
BEM代表 區塊(block),元素(element),修飾符(modifier)」,我們常用這三個實體開發組件。
在選擇器中,由以下三種符合來表示擴展的關係:
- dash :僅作為連字符使用,表示某個塊或者某個子元素的多單詞之間的連接記號。
__ Two underline:雙下划線用來連接塊和塊的子元素
-- Two dash:雙減號用來描述一個塊或者塊的子元素的一種狀態
type-block__element--modifier
一個區塊是設計或佈局的一部分,它有具體且唯一地意義 ,要麼是語義上的要麼是視覺上的。
在大多數情況下,任何獨立的頁面元素(或複雜或簡單)都可以被視作一個區塊。它的HTML容器會有一個唯一的CSS類名,也就是這個區塊的名字。
針對塊的CSS類名會加一些前綴( ui-),這些前綴在CSS中有類似 name space 的作用。
一個區塊的定義有下面三個基本原則:
例如:一個自定義列表 .product 是一個區塊,通常自定義列表是算在 mod 類別的,在這種情況下,一個 product 列表的block寫法應該為:
.product
塊中的子元素是塊的子元素,並且子元素的子元素在 BEM 里也被認為是塊的直接子元素。一個塊中元素的類名必須用父級塊的名稱作為前綴。
如上面的例子,li.item 是列表的一個子元素,
.list{}
.list .item{}
.list{}
.list__item{}
這裡可以使用偽嵌套寫成
.list {
&__item {}
}
一個「修飾符」可以理解為一個塊的特定狀態,標識著它持有一個特定的屬性。
用一個例子來解釋最好不過了。一個表示按鈕的塊默認有三個大小:小,中,大。為了避免創建三個不同的塊,最好是在塊上加修飾符。這個修飾符應該有個名字(比如:size )和值( small,normal 或者 big )。
如上面的例子中,表示一個選中的列表,和一個激活的列表項
原本的寫法
.list {}
.list.select {}
.list .item {}
.list .item.active {}
用 BEM 的寫法
.list {}
.list--select {}
.list__item {}
.list__item--active {}
用偽嵌套優化之後為
.list {
&--select {}
&__item {
&--active {}
}
}
使用 & 符號進行偽嵌套
.product {}
.product__item {}
等同於
.product {
&__item {}
}
原則以 B + E + M 完成,不得使用 B + E + E + M,或是 B + B + E + M 之類的寫法
兩層是指從 sass compiler 後的 CSS 不得有超過兩層階層
.product {
&__item {
&--selected {}
}
}
上面的 SASS 寫法這樣其實也才一層而已哦,因為 compiler 出來之後是
.product {}
.product__item {}
.product__item--selected {}
.list {
&__item > a {}
}
這樣寫只會在 list__item 下一階層的第一個 a tag 會有效果而已,如果在這底下有兩個 a tag ,第二個會失效,這是特別要注意的點。
BEM是不允許用 Tag selector 的
.menu li 能搞定的事情需要每個 li 都寫 .menu-item
優點: 就是避免 li 裡的 li 受影響 舉個例子,商品詳情頁是允許商家自定義標籤的,那麼商家展示區域標籤的祖先元素一旦用標籤選擇器定義了樣式,子子孫孫都要背負.
所以十分贊同在無法百分百確定不會嵌套同樣標籤的情況下不用 Tag selector
組件之間的完全解耦,不會造成命名空間的污染,如: .mod-xxx ul li 的寫法帶來的潛在的嵌套風險。
BEM 命名會使得 Class 類名變長,但經過 gzip 壓縮後這個帶寬開銷可以忽略不計
/* Header */
內容區
/* End Header */
注意事項::
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。