人們問我最多的問題之一是在CSS類名中--
和__
是什麼意思?它們的出現是源於BEM和Nicolas Gallagher...css
BEM的意思就是塊(block)、元素(element)、修飾符(modifier),是由Yandex團隊提出的一種前端命名方法論。這種巧妙的命名方法讓你的CSS類對其餘開發者來講更加透明並且更有意義。BEM命名約定更加嚴格,並且包含更多的信息,它們用於一個團隊開發一個耗時的大項目。html
重要的是要注意,我使用的基於BEM的命名方式是通過Nicolas Gallagher修改過的。這篇文章中介紹的這種命名技術並非原始的BEM,但倒是一個我更喜歡的改進版。不管實際使用了什麼樣的符號,它們其實都是基於一樣的BEM原則。前端
命名約定的模式以下:git
.block{} .block__element{} .block--modifier{}
.block
表明了更高級別的抽象或組件。.block__element
表明.block的後代,用於造成一個完整的.block的總體。.block--modifier
表明.block的不一樣狀態或不一樣版本。之因此使用兩個連字符和下劃線而不是一個,是爲了讓你本身的塊能夠用單個連字符來界定,如:github
.site-search{} /* 塊 */ .site-search__field{} /* 元素 */ .site-search--full{} /* 修飾符 */
BEM的關鍵是光憑名字就能夠告訴其餘開發者某個標記是用來幹什麼的。經過瀏覽HTML代碼中的class屬性,你就可以明白模塊之間是如何關聯的:有一些僅僅是組件,有一些則是這些組件的子孫或者是元素,還有一些是組件的其餘形態或者是修飾符。咱們用一個類比/模型來思考一下下面的這些元素是怎麼關聯的:web
.person{} .person__hand{} .person--female{} .person--female__hand{} .person__hand--left{}
頂級塊是‘person’,它擁有一些元素,如‘hand’。一我的也會有其餘形態,好比女性,這種形態進而也會擁有它本身的元素。下面咱們把他們寫成‘常規’CSS:segmentfault
.person{} .hand{} .female{} .female-hand{} .left-hand{}
這些‘常規’CSS都是有意義的,可是它們之間卻有些脫節。就拿.female來講,是指女性人類仍是某種雌性的動物?還有.hand,是在說一隻鐘錶的指針(譯註:英文中hand有指針的意思)?仍是一隻正在玩紙牌的手?使用BEM咱們能夠得到更多的描述和更加清晰的結構,單單經過咱們代碼中的命名就能知道元素之間的關聯。BEM真是強大。app
再來看一個以前用‘常規’方式命名的.site-search的例子:編輯器
<form class="site-search full"> <input type="text" class="field"> <input type="Submit" value ="Search" class="button"> </form>
這些CSS類名真是太不精確了,並不能告訴咱們足夠的信息。儘管咱們能夠用它們來完成工做,但它們確實很是含糊不清。用BEM記號法就會是下面這個樣子:工具
<form class="site-search site-search--full"> <input type="text" class="site-search__field"> <input type="Submit" value ="Search" class="site-search__button"> </form>
咱們能清晰地看到有個叫.site-search
的塊,他內部是一個叫.site-search__field
的元素。而且.site-search
還有另一種形態叫.site-search--full
。
咱們再來舉個例子……
若是你熟悉OOCSS(面向對象CSS),那麼你對media對象必定也不陌生。用BEM的方式,media對象就會是下面這個樣子:
.media{} .media__img{} .media__img--rev{} .media__body{}
從這種CSS的寫法上咱們就已經知道.media__img
和.media__body
必定是位於.media
內部的,並且.media__img--rev
是.media__img
的另外一種形態。僅僅經過CSS選擇器的名字咱們就能獲取到以上所有信息。
BEM的另一個好處是針對下面這種狀況:
<div class="media"> <img src="logo.png" alt="Foo Corp logo" class="img-rev"> <div class="body"> <h3 class="alpha">Welcome to Foo Corp</h3> <p class="lede">Foo Corp is the best, seriously!</p> </div> </div>
光從上面的代碼來看,咱們根本不明白.media和.alpha兩個class彼此之間是如何相互關聯的?一樣咱們也無從知曉.body和.lede之間,或者.img-rev
和.media之間各是什麼關係?從這段HTML(除非你對那個media對象很是瞭解)中咱們也不知道這個組件是由什麼組成的和它還有什麼其餘的形態。若是咱們用BEM方式重寫這段代碼:
<div class="media"> <img src="logo.png" alt="Foo Corp logo" class="media__img--rev"> <div class="media__body"> <h3 class="alpha">Welcome to Foo Corp</h3> <p class="lede">Foo Corp is the best, seriously!</p> </div> </div>
咱們立馬就能明白.media
是一個塊,.media__img--rev
是一個加了修飾符的.media__img
的變體,它是屬於.media
的元素。而.media__body
是一個還沒有被改變過的也是屬於.media
的元素。全部以上這些信息都經過它們的class名稱就能明白,由此看來BEM確實很是實用。
一般人們會認爲BEM這種寫法難看。我敢說,若是你僅僅是由於這種代碼看上去不怎麼好看而羞於使用它,那麼你將錯失最重要的東西。除非使用BEM讓代碼增長了沒必要要的維護困難,或者這麼作確實讓代碼更難讀了,那麼你在使用它以前就要三思而行了。可是,若是隻是「看起來有點怪」而事實上是一種有效的手段,那麼咱們在開發以前固然應該充分考慮它。
是,BEM看上去確實怪怪的,可是它的好處遠遠超過它外觀上的那點瑕疵。
BEM可能看上去有點滑稽,並且有可能致使咱們輸入更長的文本(大部分編輯器都有自動補全功能,並且gzip壓縮將會讓咱們消除對文件體積的擔心),可是它依舊強大。
我在個人全部項目中都使用了BEM記號法,由於它的有效性已經被它本身一次又一次地證實。我也極力地建議別人使用BEM,由於它讓全部東西之間的聯繫變得更加緊密,讓團隊甚至是你我的都可以更加容易地維護代碼。
然而,當你真正使用BEM的時候,重要的是,請記住你不必真的在每一個地方都用上它。好比:
.caps{ text-transform:uppercase; }
這條CSS不屬於任何一個BEM範疇,它僅僅只是一條單獨的樣式。
另外一個沒有使用BEM的例子是:
.site-logo{}
這是一個logo,咱們能夠把它寫成BEM格式,像下面這樣:
.header{} .header__logo{}
但咱們不必這麼作。使用BEM的訣竅是,你要知道何時哪些東西是應該寫成BEM格式的。由於某些東西確實是位於一個塊的內部,但這並不意味它就是BEM中所說的元素。這個例子中,網站logo徹底是恰巧在.header的內部,它也有可能在側邊欄或是頁腳裏面。一個元素的範圍可能開始於任何上下文,所以你要肯定只在你須要用到BEM的地方你才使用它。再看一個例子:
<div class="content"> <h1 class="content__headline">Lorem ipsum dolor...</h1> </div>
在這個例子裏,咱們也許僅僅只須要另外一個class,能夠叫它.headline;它的樣式取決於它是如何被層疊的,由於它在.content的內部;或者它只是恰巧在.content的內部。若是它是後者(即恰巧在.content的內部,而不老是在)咱們就不須要使用BEM。
然而,一切都有可能潛在地用到BEM。咱們再來看一下.site-logo的例子,想象一下咱們想要給網站增長一點聖誕節的氣氛,因此咱們想有一個聖誕版的logo。因而咱們有了下面的代碼:
.site-logo{} .site-logo--xmas{}
咱們能夠經過使用--修飾符來快速地爲咱們的代碼構建另外一個版本。
BEM最難的部分之一是明確做用域是從哪開始和到哪結束的,以及何時使用(不使用)它。隨着接觸的多了,有了經驗積累,你慢慢就會知道怎麼用,這些問題也再也不是問題。
因此,BEM(或BEM的變體)是一個很是有用,強大,簡單的命名約定,以致於讓你的前端代碼更容易閱讀和理解,更容易協做,更容易控制,更加健壯和明確並且更加嚴密。
儘管BEM看上去多少有點奇怪,可是不管什麼項目,它對前端開發者都是一個巨有價值的工具。
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了我的對技術的理解。若是翻譯有不對之處,還煩請同行朋友指點。謝謝!
by 大漠
原文 MindBEMding – getting your head ’round BEM syntax
翻譯 David