CSS 命名管理 之 BEM


好吧,將 BEM 簡單的解釋為 “Block-Element-Modifier“, 其實是個不負責任的做法。鬼知道 Block 是什么啊?所以,看了一些似懂非懂的中文解釋之后,自己還是得去找些英文來讀一讀,順便總結一下。

本人對 HTML、JavaScript、CSS 其實都只是一知半解,所以,如果有理解不到位的,還望各位看官斧正。但是,本着“要學就要學最先進”的原則,即使是基礎不扎實,還是要沖着更有效率的方式前進。

有不想看我羅嗦的看官,可以直接看下面這篇文檔:

https://css-tricks.com/bem-101/

 

什么是 BEM

我們借助一個實例,來對 BEM 做一下介紹。下面是一個遵照 BEM 規則寫的 CSS:

/* Block */
.btn {
  text-decoration: none;
  background-color: white;
  color: #888;
  border-radius: 5px;
  display: inline-block;
  margin: 10px;
  font-size: 18px;
  text-transform: uppercase;
  font-weight: 600;
  padding: 10px 5px;
}

/* Element */
.btn__price {
  background-color: white;
  color: #fff;
  padding-right: 12px;
  padding-left: 12px;
  margin-right: -10px; /* realign button text padding */
  font-weight: 600;
  background-color: #333;
  opacity: .4;
  border-radius: 5px 0 0 5px;
}

/* Element */
.btn__text {
  padding: 0 10px;
  border-radius: 0 5px 5px 0;
}

/* Modifier */
.btn--big {
  font-size: 28px;
  padding: 10px;
  font-weight: 400;
}

/* Modifier */
.btn--blue {
  border-color: #0074D9;
  color: white;
  background-color: #0074D9;
}

/* Modifier */
.btn--orange {
  border-color: #FF4136;
  color: white;
  background-color: #FF4136;
}

/* Modifier */
.btn--green {
  border-color: #3D9970;
  color: white;
  background-color: #3D9970;
}


body {
  font-family: "fira-sans-2", sans-serif;
  background-color: #ccc;
}
View Code

然后,我們把它應用到這個頁面上:

<a href="http://git.oschina.net/" class="btn">
  <span class="btn__text">Standard button</span>
</a>

<a href="http://git.oschina.net/" class="btn btn--orange btn--big">
  <span class="btn__price">$3</span>
  <span class="btn__text">Big button</span>
</a>

<a href="http://git.oschina.net/" class="btn btn--blue btn--big">
  <span class="btn__price">$4</span>
  <span class="btn__text">Big button</span>
</a>

<a href="http://git.oschina.net/" class="btn btn--green btn--big">
  <span class="btn__price">$9</span>
  <span class="btn__text">Big button</span>
</a>

於是,我們得到了這樣的結果:

很顯然,這里的 block 只是被命名為 btn,而不是 HTML 里的那個 button 對象; block 只是我們的一個處理單元,對它的定義貌似沒有特殊要求,甚至它是可以包含其他 block 的。那么,另一個概念“ Element ”也就呼之欲出了,組成 Block 的,當然就是它的元素。顯然,Element 是針對,也是依賴於 Block 存在的。而 modifier 則是簡單的對 block 某些屬性的重寫。

重中之重!從 CSS 代碼里面,我們就可以看到,element 和 modifier 是從屬於 block的!從哪里可以看出來?命名!好吧,只是開個玩笑。在這里,element 被命名為 block__ele的形式(btn__txt, btn__price), modifier 則被命名為 block--mod的形式(btn--orange);你可以把連接符換成你喜歡的符號,但是“--”,“__”是大家都推薦的。對於同一個 block 的不同定制需求,我們只需要添加新的 modifier 就好,是不是很方便?

 

為什么需要 BEM

當然,寫個小網頁沒關系,反正就那么幾個控件,你隨便怎么命名都無所謂。但是,頁面大了,參與的人員多了,命名的識別度、以及一致性就成了大問題;另一種情況,假設每個人都有一套獨立的命名規則,這樣是可以在很大程度上避免命名污染的,但也走向了另一個極端 —— CSS 文件變得很龐大。所以,就出現了這樣一類技術,which aimed on reducing CSS codebase and organizing programmers cooperation and maintaining of CSS code。比如,OOCSS,SMACSS,SUITCSS,Atomic CSS等。

那么,BEM 相比之下的優勢在哪里呢?正如我們知道的那樣,使用命名管理和不使用命名管理,肯定是有本質上的區別的,就像是開汽車和走路一樣;同時,汽車有電動的、汽油的、柴油的等等,還有越野的和普通代步的,適用性和效率差別也是很大的。所以,如果你已經在使用命名管理,那就已經是很有效率了。至於 BEM 的優勢,大家眾說紛紜,就我看到的,簡單概括。首先是命名識別度高,結構清晰。element 和 modifier 與 block 之間的從屬關系,可以從名稱上就一目了然的區分。其次,命名隔離性好。每一個 Block 都有一個獨立的空間,很好的控制了對其他元素的污染。再次,良好的擴展性。如果新的 block 只是和原來的 block 有不同的背景顏色,那么,只需要再創建一個新的 modifier。最后,它可以很好的和 Javascript (DOM)很好的整合,在針對某個 block 的操作里,所有元素的名稱都是一致的。

 

偽 BEM

據說這是應用 BEM 常犯的一個錯誤。這樣的 CSS :

.nav .nav__listItem .btn--orange {
  background-color: green;
}

這樣的 html:

<a class="btn" href="http://css-tricks.com">
  <div class="nav__listItem">Item one</div>
  <div class="nav__listItem">Item two</div>
</a>

雖然看着像是 BEM, 但是,是不是有種神經錯亂的感覺?雖然頁面看起來是一樣的,但是。。。我想說,如果是這樣,你還是按自己想法寫個名字給我猜好了,說不定我還能猜到你寫的啥。所以,然后,又有人給出了這樣的建議:

  • Never overriding modifiers in an unrelated block.
  • Avoiding making unnecessary parent elements when the child can exist quite happily by itself.

翻譯為人話就是:結構清晰,嚴格執行 element 和 modifier 與 block 的從屬關系; block 嵌套的層次要盡量少(他能搞得定,就不要給他再搞個爹)。

 

好吧,另外一篇講 BEM 的:

http://www.w3cplus.com/css/bem-definitions.html

這篇也不錯:

http://getbem.com/introduction/

http://nicolasgallagher.com/about-html-semantics-front-end-architecture/


免責聲明!

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



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