CSS 命名管理 之 BEM

好吧,将 BEM 简单的解释为 “Block-Element-Modifier“, 实际上是个不负责任的作法。鬼知道 Block 是什么啊?因此,看了一些似懂非懂的中文解释以后,本身仍是得去找些英文来读一读,顺便总结一下。css

本人对 HTML、JavaScript、CSS 其实都只是只知其一;不知其二,因此,若是有理解不到位的,还望各位看官斧正。可是,本着“要学就要学最早进”的原则,即便是基础不扎实,仍是要冲着更有效率的方式前进。html

有不想看我罗嗦的看官,能够直接看下面这篇文档:git

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

 

什么是 BEMide

咱们借助一个实例,来对 BEM 作一下介绍。下面是一个遵守 BEM 规则写的 CSS:oop

/* 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

而后,咱们把它应用到这个页面上:ui

<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>

因而,咱们获得了这样的结果:spa

很显然,这里的 block 只是被命名为 btn,而不是 HTML 里的那个 button 对象; block 只是咱们的一个处理单元,对它的定义貌似没有特殊要求,甚至它是能够包含其余 block 的。那么,另外一个概念“ Element ”也就呼之欲出了,组成 Block 的,固然就是它的元素。显然,Element 是针对,也是依赖于 Block 存在的。而 modifier 则是简单的对 block 某些属性的重写。.net

重中之重!从 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/