4

使用 BEM 之後的 CSS 書寫規範

 2 years ago
source link: https://blog.niclin.tw/2017/08/21/%E4%BD%BF%E7%94%A8-bem-%E4%B9%8B%E5%BE%8C%E7%9A%84-css-%E6%9B%B8%E5%AF%AB%E8%A6%8F%E7%AF%84/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

我們平時最開始學習寫 CSS 代碼的時候,我們都是這麼寫的:

.main-part .tabs {
  /*...*/
}

其實這樣的寫法是不好的,因為它過度的與頁面中的某一部分耦合了。我們在軟件工程的思想中追求的就是解耦。

BEM 風格不只一種

BEM 的命名規範不是死的,可以參考 bem-conventions

這裡有一些可供選擇的基於 BEM 命名約定的方案。

Two Dashes style(雙連字符風格)

block-name__elem-name--mod-name

  • 名字全部使用小寫。
  • BEM 實體的名稱中的每一個單詞使用一個連字符分隔。
  • 使用雙下划線(__)將元素的名稱和模塊的名稱分離開。
  • 使用雙連字符(–)分隔 Boolean 類型的修飾符。
  • 不使用 key-value 類型的修飾符
  • 重要提示!在注釋中,雙連字符被視為注釋的一部分,因此在文檔驗證時,雙破折號可能會引起錯誤。HTML5 Specification

CamelCase style(駝峰命名風格)

MyBlock__SomeElem_modName_modVla

這種風格的命名方案的不同點在於,在 BEM 實體中分隔單詞時使用駝峰命名法代替了一個連字符(-)。

“Sans underscore” style(無下划線風格)

blockName-elemName--modName--modVal

名稱使用駝峰命名法書寫。 元素名稱與模塊名稱使用一個連字符(-)分隔。 修飾符使用雙連字符(–)與模塊或元素分隔, 修飾符的名稱和值使用雙連字符(–)分隔。 重要提示!

在注釋中,雙連字符被視為注釋的一部分,因此在文檔驗證時,雙破折號可能會引起錯誤。HTML5 Specification

BEM 說明(這裡用 Two Dashes style(雙連字符風格))說明

在這邊使用 BEM 的命名規範,每行 CSS 代碼都只有一個選擇器

BEM代表 區塊(block),元素(element),修飾符(modifier)」,我們常用這三個實體開發組件。

在選擇器中,由以下三種符合來表示擴展的關係:

-   dash :僅作為連字符使用,表示某個塊或者某個子元素的多單詞之間的連接記號。
__  Two underline:雙下划線用來連接塊和塊的子元素
--  Two dash:雙減號用來描述一個塊或者塊的子元素的一種狀態

type-block__element--modifier

區塊(block)

一個區塊是設計或佈局的一部分,它有具體且唯一地意義 ,要麼是語義上的要麼是視覺上的。

在大多數情況下,任何獨立的頁面元素(或複雜或簡單)都可以被視作一個區塊。它的HTML容器會有一個唯一的CSS類名,也就是這個區塊的名字。

針對塊的CSS類名會加一些前綴( ui-),這些前綴在CSS中有類似 name space 的作用。

一個區塊的定義有下面三個基本原則:

  1. CSS中只能使用類名(不能是ID)。
  2. 每一個區塊名應該有一個命名空間(前綴)
  3. 每一條CSS規則必須屬於一個區塊。

例如:一個自定義列表 .product 是一個區塊,通常自定義列表是算在 mod 類別的,在這種情況下,一個 product 列表的block寫法應該為:

.product 

元素(element)

塊中的子元素是塊的子元素,並且子元素的子元素在 BEM 里也被認為是塊的直接子元素。一個塊中元素的類名必須用父級塊的名稱作為前綴。

如上面的例子,li.item 是列表的一個子元素,

.list{}
.list .item{}


.list{}
.list__item{}

這裡可以使用偽嵌套寫成

.list {
    &__item {}
}

修飾符(modifier)

一個「修飾符」可以理解為一個塊的特定狀態,標識著它持有一個特定的屬性。

用一個例子來解釋最好不過了。一個表示按鈕的塊默認有三個大小:小,中,大。為了避免創建三個不同的塊,最好是在塊上加修飾符。這個修飾符應該有個名字(比如:size )和值( smallnormal 或者 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 ,第二個會失效,這是特別要注意的點。

不要使用 Tag selector

BEM是不允許用 Tag selector 的

.menu li 能搞定的事情需要每個 li 都寫 .menu-item

優點: 就是避免 li 裡的 li 受影響 舉個例子,商品詳情頁是允許商家自定義標籤的,那麼商家展示區域標籤的祖先元素一旦用標籤選擇器定義了樣式,子子孫孫都要背負.

所以十分贊同在無法百分百確定不會嵌套同樣標籤的情況下不用 Tag selector

BEM 解決問題

組件之間的完全解耦,不會造成命名空間的污染,如: .mod-xxx ul li 的寫法帶來的潛在的嵌套風險。

BEM 命名會使得 Class 類名變長,但經過 gzip 壓縮後這個帶寬開銷可以忽略不計

延伸閱讀 - 常用的CSS命名規則

  • 頭:header
  • 內容:content/container
  • 尾:footer
  • 導航:nav
  • 側欄:sidebar
  • 欄目:column
  • 頁面外圍控制整體佈局寬度:wrapper
  • 左右中:left right center
  • 登錄條:loginbar
  • 標誌:logo
  • 廣告:banner
  • 頁面主體:main
  • 熱點:hot
  • 新聞:news
  • 下載:download
  • 子導航:subnav
  • 菜單:menu
  • 子菜單:submenu
  • 搜索:search
  • 友情鏈接:friendlink
  • 頁腳:footer
  • 版權:copyright
  • 滾動:scroll
  • 內容:content
  • 標籤:tags
  • 文章列表:list
  • 提示信息:msg
  • 小技巧:tips
  • 欄目標題:title
  • 加入:joinus
  • 指南:guide
  • 服務:service
  • 註冊:regsiter
  • 狀態:status
  • 投票:vote
  • 合作夥伴:partner

注釋的寫法:

/* Header */
內容區
/* End Header */

Id的命名:

  • 容器: container
  • 頁頭:header
  • 內容:content/container
  • 頁面主體:main
  • 頁尾:footer
  • 導航:nav
  • 側欄:sidebar
  • 欄目:column
  • 頁面外圍控制整體佈局寬度:wrapper
  • 左右中:left right center
  • 導航:nav
  • 主導航:mainnav
  • 子導航:subnav
  • 頂導航:topnav
  • 邊導航:sidebar
  • 左導航:leftsidebar
  • 右導航:rightsidebar
  • 菜單:menu
  • 子菜單:submenu
  • 標題: title
  • 摘要: summary
  • 標誌:logo
  • 廣告:banner
  • 登陸:login
  • 登錄條:loginbar
  • 註冊:register
  • 搜索:search
  • 功能區:shop
  • 標題:title
  • 加入:joinus
  • 狀態:status
  • 按鈕:btn
  • 滾動:scroll
  • 標籤頁:tab
  • 文章列表:list
  • 提示信息:msg
  • 當前的: current
  • 小技巧:tips
  • 圖標: icon
  • 注釋:note
  • 指南:guild
  • 服務:service
  • 熱點:hot
  • 新聞:news
  • 下載:download
  • 投票:vote
  • 合作夥伴:partner
  • 友情鏈接:link
  • 版權:copyright

注意事項::

  1. 一律小寫;
  2. 盡量用英文;
  3. 盡量不縮寫,除非一看就明白的單詞。

CSS樣式表文件命名

  • 主要的 master.css
  • 模塊 module.css
  • 基本共用 base.css
  • 佈局、版面 layout.css
  • 主題 themes.css
  • 專欄 columns.css
  • 文字 font.css
  • 表單 forms.css
  • 補丁 mend.css
  • 打印 print.css

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK