前面的話 每次寫HTML結構涉及到CSS命名時,都要掙扎一番。關於CSS命名的規範,市面上有不少,如OOCSS、SMACSS、BEM和MVCSS等。在這裡面最火的應該算BEM了。本文將詳細介紹CSS命名 主流命名 【BEM】 說起CSS命名,當然要提到BEM。BEM的意思就是B模塊(block)、E ...
前面的話
每次寫HTML結構涉及到CSS命名時,都要掙扎一番。關於CSS命名的規範,市面上有不少,如OOCSS、SMACSS、BEM和MVCSS等。在這裡面最火的應該算BEM了。本文將詳細介紹CSS命名
主流命名
【BEM】
說起CSS命名,當然要提到BEM。BEM的意思就是B模塊(block)、E元素(element)、M修飾符(modifier)。模塊和子元素之間用兩個下劃線分隔,子元素和修飾符之間用兩個中劃線分隔
關於子元素E,有兩種寫法。一種是按照層級嵌套來寫,如block-ele1-son-inner
,但是這樣寫會導致命名過長;另一種是扁平化,一個模塊B下的所有子元素,無論相互層級如何,都直接連接B,如block-inner
,但是這樣就無法表示層級關係,命名時也可能會出現衝突
BEM的命名是很好的,不然也不能成為最流行的命名方法。但是,BEM對子元素的命名,無論是層級長命名還是扁平化短命名,都有缺陷
【NEC】
相較於BEM以模塊B為頂級元素,子元素類名中包含繼承關係的命名,網易的NEC規範使用後代選擇器方式
NEC將元素分為了5類:佈局(grid)(.g-);模塊(module)(.m-);元件(unit)(.u-);功能(function)(.f-);皮膚(skin)(.s-);狀態(.z-)。而後代選擇器不需要完整表現結構樹層級,儘量能短則短
.m-list{margin:0;padding:0;} .m-list .itm{margin:1px;padding:1px;} .m-list .cnt{margin-left:100px;}
個人認為,網易對於元素分類的做法很好。關於一些全局可復用的功能性的模塊進行區分,結構更為清晰。但是,對於使用後代選擇器的方式,個人不太認同。當嵌套層級較深時,命名衝突依舊是一個問題
【JD】
京東的命名規則採用表示層級嵌套關係的長命名。當子孫模塊超過4級或以上的時候,考慮在祖先模塊內具有識辨性的獨立縮寫作為新的子孫模塊
<div class="modulename"> <div class="modulename_cover"></div> <div class="modulename_info"> <div class="modulename_info_user"> <div class="modulename_info_user_img"> <img src="" alt=""> <!-- 這個時候 miui 為 modulename_info_user_img 首字母縮寫--> <div class="miui_tit"></div> <div class="miui_txt"></div> ... </div> </div> <div class="modulename_info_list"></div> </div> </div>
京東這種因數元素名字過長而採用首字母縮寫的做法非常贊,至今市面上沒有其他更好的解決長命名的方案
命名方式
【後代選擇器還是類名】
關於CSS命名,最大的爭論就是使用後代選擇器還是使用類名。以下例所示
<ul class="list"> <li class="list-item"></li> <li class="list-item"></li> <li class="list-item"></li> </ul> <ul class="list"> <li class="item"></li> <li class="item"></li> <li class="item"></li> </ul> <ul class="list"> <li></li> <li></li> <li></li> </ul>
如果採用第一種長類名的方式,為<li>元素設置樣式,只需如下設置即可
.list-item{}
如果採用第二種短類名的方式,則為<li>元素設置樣式,需如下設置
.list .item{}
如果採用第三種後代選擇器的方式,則為<li>元素設置樣式,需如下設置
.list li{}
如果從簡易角度來看,第三種後代選擇器的方式最簡單,無需花時間去給子元素起名,且在sass中書寫很容易
.list{
li{}
}
但是,它有一個很嚴重的問題,就是如果HTML結構層級較深,往往出現選擇器層級過長,如.list li span a{}
而且,因為後代選擇器強烈地依賴HTML結構,為了避免因為少寫一層結構,導致選擇器特殊性降低,樣式無法生效的情況,也不得不這樣寫
一個不得不提的問題是,CSS選擇器的解析順序是從右到左。而使用後代選擇器.list li{},瀏覽器需要遍歷出所有的li,再找出.list下的li,效率是最低的
因此,個人認為第三種後代選擇器的方式並不是好選擇
下麵介紹第二種短類名的方式
1、選擇器解析效率比第三種方式好,畢竟.item比li的範圍小很多
2、短類名.list .item同樣存在依賴HTML結構的情況,很可能出現選擇器層級過長
3、使用較簡易,在sass中書寫容易,且起名也較簡單
4、由於給li增加了類名,於是增加了HTML文件大小
最後介紹第三種長類名的方式
這種方式的選擇器效率最高,因為.list-item這個類型頁面中只出現一次,可類比於id選擇器的解析速度
由於使用長類名的方式,可以完全不使用後代選擇器,則無需考慮選擇器特殊性較低,樣式無法生效的情況,也不會出現選擇器層級過長,因為它僅有一級
但是,相應地,它最大的缺點是類名較長,大大地增加了HTML文件大小。於是,可借鑒京東,當子孫模塊超過3級時,採用首字母縮寫,並將縮寫後首字母大寫的做法,在如將.list-item-link-title縮寫為.Lil-title
最終,選擇可縮寫的長類名作為CSS命名的主要方式
【分隔符】
一般地,classname分隔符有3種,中劃線-,下劃線_,以及首字母大寫,以分隔list和item為例
//中劃線
list-item
//下劃線
list_item
//首字母大寫
listItem
1、中劃線
中劃線可以用來表示層級關係
<div class="box"> <ul class="box-list"> <li class="box-list-item"></li> <li class="box-list-item"></li> <li class="box-list-item"></li> </ul> </div>
2、下劃線
下劃線可以用來表示不同的狀態
<div class="box"> <button class="box-btn box-btn_default" type="button"></button> <button class="box-btn" type="button"></button> </div>
3、首字母大寫
首字母大寫可以用來表示因為樣式的需要,而不得不增加的HTML結構。一般地,如果在外層增加結構,可以增加Wrap,在內層增加結構,可以增加Inner,且不影響原先的classname的命名
<div class="boxWrap"> <section class="box"> <h2 class="box-title"></h2> <p class="box-content"></p> </section> </div>
【組件】
通過上面的長命名方式和分隔符的使用,解決了基礎結構的命名。但是,在頁面中,很可能出現一些組件的應用,這些組件可以復用到頁面的多個位置。這時,再使用上面的方式就不太合適
於是,可以以m-為首碼,來表示這是一個組件
<div class="box"> <button class="m-btn m-btn_error" type="button"></button> <button class="m-btn" type="button"></button> </div>
命名推薦
有了合適的命名方式,還需要語義化命名,且有不影響語義的情況下,可以簡寫
【佈局】
文檔 doc
頭部 header(hd)
主體 body
尾部 footer(ft)
主欄 main
側欄 side
容器 box/container
【通用部件】
列表 list
列表項 item
表格 table
表單 form
鏈接 link
標題 caption/heading/title
菜單 menu
集合 group
條 bar
內容 content
結果 result
【組件】
按鈕 button(btn)
字體 icon
下拉菜單 dropdown
工具欄 toolbar
分頁 page
縮略圖 thumbnail
警告框 alert
進度條 progress
導航條 navbar
導航 nav
子導航 subnav
麵包屑 breadcrumb(crumb)
標簽 label
徽章 badge
巨幕 jumbotron
面板 panel
窪地 well
標簽頁 tab
提示框 tooltip
彈出框 popover
輪播圖 carousel
手風琴 collapse
定位浮標 affix
【語義化小部件】
品牌 brand
標誌 logo
額外部件 addon
版權 copyright
註冊 regist(reg)
登錄 login
搜索 search
熱點 hot
幫助 help
信息 info
提示 tips
開關 toggle
新聞 news
廣告 advertise(ad)
排行 top
下載 download
【功能部件】
左浮動 fl
右浮動 fr
清浮動 clear
【狀態】
前一個 previous
後一個 next
當前的 current
顯示的 show
隱藏的 hide
打開的 open
關閉的 close
選中的 selected
有效的 active
預設的 default
反轉的 toggle
禁用的 disabled
危險的 danger
主要的 primary
成功的 success
提醒的 info
警告的 warning
出錯的 error
大型的 lg
小型的 sm
超小的 xs
實踐
<header class="hd"> <nav class="hd-navbar m-navbar m-varbar_primary"> <div class="hd-navbar-tel">聯繫方式:400-888-8888</div> <ul class="hd-navbar-nav"> <li class="Hnn-itm m-btn m-btn_info"><a href="#">登錄</a></li> <li class="Hnn-itm m-btn"><a href="#">快速註冊</a></li> <li class="Hnn-itm m-btn"><a href="#">關於</a></li> <li class="Hnn-itm m-btn"><a href="#">幫助</a></li> </ul> </nav> ... </header>
關於CSS命名,並沒有最佳實踐之說,根據項目的複雜程式進行合適的命名才是可取的
歡迎交流