bem什么意思_BEM命名法
摘要
當(dāng)你在編寫css代碼的時(shí)候,是否遇到這樣的困擾: 不知道取什么class名? 修改某個(gè)組件的樣式,擔(dān)心影響了其他組件? 編寫的組件樣式如何復(fù)用?為了解決這些問題,聰明的程序猿發(fā)明了BEM命名法。
BEM命名法,是對css命名的一種規(guī)范,將頁面模塊化,隔離樣式,提高代碼的復(fù)用性,減少后期的維護(hù)成本。BEM的意思就是Block(塊)、Element(元素)、modifier(修飾符),通過雙下劃線__或者雙中劃--鏈接。
BEM通常用于框架開發(fā)中,比如微信WEUI、餓了么element-ui、有贊vant等。筆者也是通過閱讀這些優(yōu)秀框架的源碼,學(xué)習(xí)到了這一套css命名大法,從此走上人生巔峰,贏取白富美。
1. 為什么需要BEM命名法
樣式隔離, 避免css樣式污染
css樣式污染的根本原因,是因?yàn)閏ss沒有作用域。BEM通過特殊的命名方式,給css創(chuàng)造一個(gè)“作用域”,就能有效避免css樣式全局污染。例如,給輸入框命名
# 普通 .base input {}# BEM命名法 .base-input__inner {}普通的命名法, 會(huì)作用于所有class='base' 的后代元素。 本來你只想給當(dāng)前元素加樣式,結(jié)果不小心影響了其他元素,這就是樣式污染。
BEM命名法,只會(huì)作用于class='base-input__inner'的元素, 達(dá)到樣式隔離。 不會(huì)影響其他元素。
有人會(huì)說css-module, 也能實(shí)現(xiàn)css“作用域”,而且作用域更唯一,我為什么要用BEM ? 客官,別急,且聽我慢慢道來。
代碼更易覆蓋
假如,客官你正在開發(fā)一個(gè)通用的輸入框組件, 用了css-module。打包后是這個(gè)樣子
.base-input-sdFh3sxLwo5uer {}另一位客官,用了你的輸入框組件,但是覺得樣式不好看,想修改樣式。試了半天,發(fā)現(xiàn),根本無法用css精確選擇你的組件,因?yàn)?base-input后面的hash值是動(dòng)態(tài)的。于是,這位客官,捶胸頓足,發(fā)誓再也不用你的組件了。
代碼更易讀
還是剛剛的輸入框組件,base-input__nner, 不需要我解釋,客官一眼就能看出: base代表基礎(chǔ)組件,input代表輸入框組件, inner是組件中的某一塊。
~哇~,客官你真是太聰明了!
2. 什么是BEM命名法
BEM其實(shí)是塊(block)、元素(element)、修飾符(modifier)的縮寫,利用不同的塊,功能以及樣式來給元素命名。這三個(gè)部分使用__與--連接(這里用兩個(gè)而不是一個(gè)是為了留下用于塊的命名)。命名約定的模式如下:
.block{} .block__element{} .block--modifier{}- block代表更高級別的抽象或組件
- block__element代表 block的后代,用于形成一個(gè)完整的block的整體
- block--modifier代表block的不同狀態(tài)或不同版本
常用規(guī)范
常用的元素名
- 表單元素 form form-item input select radio checkbox switch rate datePicker
- 導(dǎo)航元素 nav subnav menu tab
- 提示 alert message messageBox notification
- 數(shù)據(jù)展示 table process tree pagiantion
- 其他 button icon
3. 如何用好BEM命名法
頁面命名
用page-開頭, page表示這是一個(gè)頁面, 而不是組件。 給頁面命名時(shí),BEM可以搭配css-module一起使用。既能保證打包后選擇器的唯一,又容易調(diào)試。例如
# 編譯前 .page-index {} .page-zufang {}# 編譯后 .page-index-70yGFBg1eKjbSIwN {} .page-zufang-mFTy62A1t83zjDbh {}使用css-module, 打包后的clss名是可以修改的 參考
# 讓打包后的文件更容易識別 {test: /.css$/,use: [{loader: 'css-loader',options: {modules: true,localIdentName: '[local]--[hash:base64:5]'}}] }頁面中的選擇器,都嵌套在頁面根選擇器內(nèi)(.page-xxx), 保證所有樣式, 只作用于當(dāng)前頁面。例如
<!- 頁面命名 page-home -> <div class="page-home"><div class="the-form"><div class="the-form-item"><div class="the-input"></div></div></div><div class="the-table"><div class="the-table-content"></div></div> </div>.page-home {.the-form {}.the-form-item {}.the-input {}.the-table {}.the-table-content {} }公共組件命名
用base-開頭, base表示公共組件。
<div class="base-input"><input class="base-input__inner"/> </div># 選擇器避免嵌套,降低選擇器權(quán)重 .base-input {} .base-input__inner {}公共組件的每一個(gè)class名,帶上組件的作用域前綴,如base-input__inner的作用域前綴是base-input。
選擇器不宜嵌套, 讓選擇器的權(quán)重盡可能低。原因如下: base-input__inner已經(jīng)具有有作用域了,無需再嵌套。 由于組件選擇器權(quán)重較低,在組件外修改組件樣式時(shí),覆蓋樣式非常方便。
局部組件命名
用the-開頭, the表示某一特定的組件。
<div class="the-header"><div class="the-header__title" /><div class="the-header__desc"> </div># 選擇器避免嵌套,降低選擇器權(quán)重 .the-header {} .the-header__title {} .the-header__desc {}局部組件的每一個(gè)class名,帶上組件的作用域前綴,如the-header__title的作用域前綴是the-header。
局部組件,也不宜嵌套, 降低選擇器權(quán)重。
局部組件也可以搭配css-module一起用,因?yàn)榫植拷M件只給少數(shù)特定頁面使用,修改樣式,可以在組件內(nèi)部直接修改。
4. 其他注意事項(xiàng)
命名語義化
怎樣衡量你的命名是語義化的?讓一個(gè)人新人,來看一下你的代碼,不需要解釋,就能知道這個(gè)類的作用,就比較語義化.
通常,可以根據(jù)模塊的功能而命名,如頁面頭部header、導(dǎo)航欄nav、主體main、側(cè)邊欄sidebar、底部footer等,這樣整個(gè)頁面看起來就比較清晰了,維護(hù)起來也比較方便。
# bad .fl { ... } .fr { ... }# good # 左浮動(dòng) .is-float-left { ... } # 右浮動(dòng) .is-float-right { ... }上面的代碼, fl、fr之類的命名,表達(dá)意思不夠清晰,要知道具體的含義,還得去看代碼。 而is-float-left, 就表達(dá)得非常清晰。
使用 class(類) 選擇器, 避免使用 id、標(biāo)簽、偽類 選擇器
標(biāo)簽、偽類 等選擇器范圍太廣,不具有“作用域”的作用,會(huì)污染全局樣式。例如,下面的代碼中,.the-header a 選擇器會(huì)選中the-header所有后代元素<a></a>
<div class="the-header"><a></a> </div> # bad .the-header a { ... }覆蓋第三方組件樣式時(shí),重新起一個(gè)class名
使用原來的class名修改樣式,可能會(huì)不小心影響了后代組件的樣式。為了消除這個(gè)隱患,可以重新起一個(gè)class名,只作用于當(dāng)前組件。例如修改ant-design的輸入框組件樣式
<div className="the-form"><Input className="the-input"> </div># bad 會(huì)影響the-form 后代的所有輸入框 .the-form .ant-input {}# good 只會(huì)只用于className='the-input'的輸入框 .the-form .the-input{}總結(jié)
- 為什么需要BEM命名法
- 什么是BEM命名法
- 如何用好BEM命名法
- 其他注意事項(xiàng)
總結(jié)
以上是生活随笔為你收集整理的bem什么意思_BEM命名法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jenkins教程(Windows版)
- 下一篇: 模糊匹配