class如何命名更規范


相信寫css的人都會遇到下面的問題:

  •  糟糕,怎么命名這個class,好像不太貼切,要是沖突了怎么辦,要不要設計成通用一點...
  •  而改別人css代碼的時候則會一直有個疑問:這個class到底是只在這個地方用了,還是其他地方都用了?

於是就有了下面的做法:

  •  最后終於被逼出了個class,簡潔也好,中英混搭也罷,看着一頭霧水也沒關系,反正最后頁面顯示出來的。
  •  這個class應該是只有這個地方用到,我可以放心寫。上線之后。如果沒問題,則暗自自我欣賞,看吧問題就這么簡單,分分鍾搞定呀;如果沖突了,則無限感慨,哎,改的時候我就隱隱不安啊,媽蛋,深坑,這是誰寫的,誰寫的!!!
  •  不好,這個class說不定其他地方也用到了,我得加個限制范圍,加個父元素?要不重新再命名個class吧,比較保險。最后如果沒問題則表示還好比較機智,怎么說哥也是混過的,還是有幾斤幾兩的;如果有問題則表示防不慎防啊,這也太太太坑了吧。

由此可見,class的命名真不是一件簡單的事,尤其還要兼顧可辨別性與可讀性。

class命名到底有多難

第一,class跟id不一樣,class本來就是設計用來可以重復利用的,而id才是設計唯一的(如果遵循BEM,class幾乎也都是唯一的了)。

第二,樣式是可以覆蓋的,而且先按照權重,再按照定義的先后順序。也許你花了十分鍾設計定義的一個class樣式,人家分分鍾就給你干掉了,這得多惱火;也許這個頁面好好的,跑到另一個頁面就跟原先的樣式有了沖突。

所以class命名的難就難在既要重復利用,又要避免樣式的沖突。如果要重復利用,那么當然是越簡單越好,越抽象可用的地方越大,太具體了就完蛋了。而如果要避免樣式沖突。BEM的方式最簡單,class都唯一了,那還沖突個毛線;其次就是通過父元素限定作用域,可以搞幾個層級,而不是單獨一個class定義樣式;還有就是追加class,來實現差異化;最后不同的頁面不同的文件,你用你的我用我的。

// BEM
.imgslide__item__img{}

// 父元素限定
.imgslide .item .img{}

// 追加class
.img{}
.img--special{}

// 不同頁面不同文件
// a.html & a.css
.img{}
// b.html & b.css
.img{}

  

總之,不管有多難,我們還是得試試去解決問題,去尋找一些規律。

class命名的發展歷程

關於class的命名,其實跟人名也差不多,如果要想別人看得懂,那關鍵還是在於可識別性。到目前為止class的命名大概經歷了下面幾個重要階段:

  •  混沌階段,沒有規則就是最好的規則
  •  原子類階段,聚集神龍現身手
  •  模塊階段,以職能划分,添加前綴
  •  BEM階段,規則有序

混沌階段

這個沒什么好說的,剛開始學html的都是這樣,名字先簡單的來,不夠再添加1,2,3什么后綴,或者中英混搭等等,如下:

h1.title
h2.title2
h2.title2-1
h2.title2-2
div.hd
div.hd-s
div.hd2
div.hd-xiangxi

  

一個字,太亂。完全無章程,規律可循,想怎么寫就怎么寫,寫到哪里是哪里。看class去猜意思很可能就是錯誤的,如.red{color:red;font-size:14px;},明明說好的紅色,卻順帶定義了個字體大小。

原子類階段

這個關鍵在於拼湊組合,足夠多的原子類拼成一個完整的樣式:

.fl{float:left;}
.fr{float:right;}
.pr{position:relative;}
.pa{position:absolute;}
.tal{text-align:left;}
.tac{text-align:center;}
.tar{text-align:right;}
.fs12{font-size:12px;}
div.fs12.fl.pr.tac
div.pa.tal

這種有兩個缺點,第一是稍微復雜點的樣式都要使用很多class組合,第二是如果要修改樣式的時候得修改html文件,而不是css樣式,而純靜態的頁面是很少的,所以如果是前后端分離的,由php或后端語言渲染頁面的話,改個樣式還要通知后端同事去修改文件,那估計人家得瘋掉。

模塊階段

到了這個時候,css經過這么多年的發展,頁面的復雜性已經翻了好幾倍了,那些無規划的混沌根本不夠用,滿眼的class看起來長得都差不多,后面全是1,2,3都不知道標到多少了,卻不知道到底是啥區別;而原子類已經不適合頻繁的修改調整更新,每更新下都是前后齊心協力。於是按職能划分的class命名規則就出現了

// l表示layout, g表示global, m表示mod,
.l-960
.l-left
.l-right
.g-red
.g-title
.g-price
.m-login
.m-breadcrumb
.m-slide

  

這種命名方式在一定程度解決了混亂不堪的問題,所有的按照職能划分看起來很美好,不過動不動加個前綴確實不怎么優雅,再者隨着mod的增加,這個以m開頭的前綴根本就不夠用,於是又亂了,有加二級前綴的,也有另起前綴的。

BEM

這個估計地球上做前端的都知道吧,實在是太火了,所以不用來解釋了。優點就是你只管寫你自己的,99.99%的幾率不會去干掉別人的樣式,class實在太長了,能一樣那得多高的幾率啊。缺點還是class太長,太長,太長,重要的事情說三遍。一般都記不住自己定義的class,寫css的時候只好對着去拷貝。然后最痛苦的就是去修改更新,明明很簡單的東西,然后你還要搞個超長的class,那叫一個煩躁,想想都懶得動手。

他山之石

其實每個命名的發展經歷都有其特定的歷史意義,也當然有其價值。所以吸取之長,棄之短缺就很好了。比喻寫簡單demo的時候,我們就可以用到混沌階段的命名,足夠簡單,不需要糾結思考;而原子類尤其是一些簡單的樣式,如一行代碼就可以搞定,起個class名甚是糾結,還不如直接上原子類;至於模塊類,說真的應用的場景就更多了,如布局,js操作類等;而BEM我們同樣可借鑒其思想,如.class.class--name使用--表示特殊化,以區分-

這里我們站在前人的肩膀上,試着去開辟一條道路,可以兼顧簡潔可讀性及可理解辨別性。當然class的簡潔肯定離不開關鍵詞的應用,這里我們先來過一遍常見的class關鍵詞。

常見class關鍵詞:

  •  布局類:header, footer, container, main, content, aside, page, section
  •  包裹類:wrap, inner
  •  區塊類:region, block, box
  •  結構類:hd, bd, ft, top, bottom, left, right, middle, col, row, grid, span
  •  列表類:list, item, field
  •  主次類:primary, secondary, sub, minor
  •  大小類:s, m, l, xl, large, small
  •  狀態類:active, current, checked, hover, fail, success, warn, error, on, off
  •  導航類:nav, prev, next, breadcrumb, forward, back, indicator, paging, first, last
  •  交互類:tips, alert, modal, pop, panel, tabs, accordion, slide, scroll, overlay,
  •  星級類:rate, star
  •  分割類:group, seperate, divider
  •  等分類:full, half, third, quarter
  •  表格類:table, tr, td, cell, row
  •  圖片類:img, thumbnail, original, album, gallery
  •  語言類:cn, en
  •  論壇類:forum, bbs, topic, post
  •  方向類:up, down, left, right
  •  其他語義類:btn, close, ok, cancel, switch; link, title, info, intro, more, icon; form, label, search, contact, phone, date, email, user; view, loading...

有了關鍵詞之后,我們先來制定一些簡單的規則

制定簡單規則:

  •  以中划線連接,如.item-img
  •  使用兩個中划線表示特殊化,如.item-img.item-img--small表示在.item-img的基礎上特殊化
  •  狀態類直接使用單詞,參考上面的關鍵詞,如.active, .checked
  •  圖標以icon-為前綴(字體圖標采用.icon-font.i-name方式命名)。
  •  模塊采用關鍵詞命名,如.slide, .modal, .tips, .tabs,特殊化采用上面兩個中划線表示,如.imgslide--full, .modal--pay, .tips--up, .tabs--simple
  •  js操作的類統一加上js-前綴
  •  不要超過四個class組合使用,如.a.b.c.d

關鍵詞及規則都有了,現在可以進入本文的核心的核心,實戰操作。

實戰操作

以布局入手,大概結構如下:

header.header>.inner-center
section.section-feature>.inner-center // if
section.section-main>.inner-center
section.section-postscript>.inner-center // if
footer.footer>.inner-center

  

具體可參考HTML整站結構設計,這里我們可以看出都是些簡單的關鍵詞,比較好理解,一看就知道是什么。

現在問題來了,如果其他地方也要用到這些關鍵詞怎么辦?

修飾關鍵詞

以header為例,我們可以添加前綴表示不同的header,如區塊頭部.block-hd(hd為header簡寫),modal頭部.modal-hd,文章頭部.article-hd

同樣標題也可以分為,頁面標題.page-tt(title的簡寫),區塊標題.block-tt等。

同樣,這給我們提出了第二個問題,如果要特殊化某個class該怎么辦?

特殊化class

以上面的tt為例,大概有三種辦法:

第一種辦法:直接修改class,將.page-tt修改成.page-user-tt(可以采用scss的%先定義共用的代碼)。

第二種辦法: 追加class特殊化,根據我們上面定義的規則,在.page-tt上追加一個class成為.page-tt.page-tt--user,注意.page-tt--user不是一個獨立的class,它使基於.page-tt這個基礎上的。

第三種辦法: 使用父類,給一個范圍,於是形成.page-user .page-tt

一般我們使用的是第二種和第三種辦法,因為這兩種都有共同的.page-tt,可以比較方便控制一些基礎共有的樣式。

由第三個通過父類控制的辦法,我們進入第三個要討論的問題,層級結構

層級

最適合層級的例子莫過於ul>li結構了,如下面的結構:

<ul>
    <li>
        <a href="#"><img src="" alt=""></a>
        <h3><a href="#"></a></h3>
        <p></p>
    </li>
</ul>

  

一般來說我們也有兩種辦法定義層級,第一種為繼承式,第二種為關鍵詞式。

// 繼承式
ul.card-list
    li.list-item
        a.item-img-link>img.item-img
        h3.item-tt>a.item-tt-link
        p.item-text

// 關鍵詞式
ul.card-list
    li.item
        a.field-img-link>img.field-img
        h3.field-tt>a.field-tt-link
        p.field-text

  

由上可以看出繼承式一般子元素接着父元素的最后一個單詞如li接着ul的list,而li的子元素接着li的item;至於關鍵詞式則完全由關鍵詞來表示層級,list>item>filed正好構成三層等級。

最后由我們的層級進入我們最后一個問題,如何控制樣式的范圍

樣式范圍

這里以騰訊課堂的課程詳細頁右邊欄為例,如下圖:

三個區塊的基礎框架為:

.aside-block.block--xxx>
    h3.block-tt
    .block-bd

  

其中.aside-block.block--xxx用到了我們的特殊化class,而.block-tt,block-bd則使用了我們的修飾關鍵詞,至於.aside-block與它的子元素之間則使用了我們上面說的繼承式層級。現在根據這個層級結構我們定義基礎樣式如下:

.aside-block{
    .block-tt{}
    .block-bd{}
}

  

假設這里的聯系機構區塊的標題不一樣,我們則可以:

.block--contact{
    .block-tt{}
}

  

當然如果本身有5個區塊,2個標題一樣,另外三個標題又一樣,也許我們就有需要給.block-tt追加一個特殊化class,或者給aside-block特殊化一個class,如:

.aside-block{
    .block-tt{
        &.block-tt--special{}
    }
    .block-bd{}
}
// 或
.aside-block{
    &..aside-block--special{
      .block-tt{}
  }
}

  

基礎框架討論完畢之后,就輪到我們的內容了,以聯系機構為例:

使用ul>li結構,所以樣式是另外一個獨立的范圍,不嵌套在之前的.aside-block里面,html及css代碼如下:

ul.contact-list
    li
        i.item-icon.icon-font.i-xxx
        a.item-tt
        p.gray

  

這里我們li沒有設置class,而p使用了一個全局的class.gray

.gray{}
.contact-list{
    li{}
    .item-icon{}
    .item-tt
}

  

同理如果我們有其他地方應用這個可以拷貝過去,而如果需要一點調整,我們可以使用父元素來控制,如這里我們可以使用.block--contact來進一步調整contact的樣式,如:

.block--contact{
    .contact-list{
        li{}
    }
}

  

至此,我們的class命名方法討論完畢,說到底就是先記住一些必備的基礎關鍵詞,然后合理應用上剛才提出的修飾關鍵詞,特殊化class,層級及最后的樣式范圍就可以了。

原文作者:結一

轉載自:http://www.w3cplus.com/css/css-class-name.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM