文章出處

前面的話

  每次寫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>

【幻燈片】

<div class="carousel">
  <div class="carousel-banner">
    <a class="carousel-banner-item Cbi_slide1 Cbi_active" href="#"></a>
    <a class="carousel-banner-item Cbi_slide2" href="#"></a>
    <a class="carousel-banner-item Cbi_slide3" href="#"></a>
    <a class="carousel-banner-item Cbi_slide4" href="#"></a>          
  </div>
  <a class="carousel-control carousel-control_prev" href="javascript:;">&lt;</a>
  <a class="carousel-control carousel-control_next" href="javascript:;">&gt;</a>
  <div class="carousel-indicators">
    <span class="carousel-indicators-item Cii_active"></span>
    <span class="carousel-indicators-item"></span>
    <span class="carousel-indicators-item"></span>
    <span class="carousel-indicators-item"></span>
  </div>
</div>

  關于CSS命名,并沒有最佳實踐之說,根據項目的復雜程序進行合適的命名才是可取的  

  歡迎交流  


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()