# CSS BEM

# 什么是BEM?

BEM的意思就是块(block)、元素(element)、修饰符(modifier)的一个简写,是由Yandex团队提出的一种前端命名方法论。这种命名方式让你的CSS类对其他开发者来说更加的透明且更有意义。BEM命名约定更加严格,包含更多的信息。

BEM主要是一种理念,它的发明者(Yandex)从未试图强制开发者使用任何具体的实现,符号或者是文件命名约定。事实上,有句话是:最合适的即是最好的。著作权归作者所有。

# 特点

BEM光凭名字就可以告诉其他开发者某个标记是用来做什么的,通过class,就可以明白模块之间是如何关联的。看着是非常丑陋的,很长,但是是非常有意义的

eg:

.navigation {}
.navigation__item {}
.navigation__item--active{}
.sub-navigation {}
.sub-navigation__item {}

# 内容

# 模块

模块的名称描述了它的目的,而不是它的状态; 模块不应该影响它所在的环境,这意味着你不应该为模块设置会影响到外部的形状(影响大小的 padding 或边框)和定位 也不应该在使用 BEM 的时候使用 CSS 标签选择器和 ID 选择器

<!-- 正确的,这个 'error' 模块是具有语义上的意义的 -->
<div class="error"></div>
<!-- 不正确的,它描述了模块的外观 -->
<div class="red-text"></div>

# 元素

是一个模块的组成部分,且不能脱离模块单独地被使用

  • 元素名称描述了它的目的(用处)(“这是什么?” —— item,text,等等。),而不是它的状态(“什么类型的,或者它看起来是什么样的?” —— 红色,大的,等等。)
  • 完整的元素名的结构是 block-name__element-name。元素的名字与模块的名字使用双下划线分隔(__)

嵌套关系

  • 元素之间可以彼此嵌套
  • 你可以拥有任意层次的嵌套级别
  • 一个元素总是一个模块的一部分,而不是另一个元素的一部分,这意味着元素的名称不能被定义为 block__elem1__elem2 这样的层次结构。
<!--
     正确的。完整的元素名的结构符合如下模式:
     'block-name__element-name'
 -->
<form class="search-form">
    <div class="search-form__content">
        <input class="search-form__input"/>
        <button class="search-form__button"></button>
    </div>
</form>

 <!--
     不正确的。完整的元素名的结构不符合如下模式:
     'block-name__element-name'
 -->
<form class="search-form">
    <div class="search-form__content">
        <!-- 推荐:'search-form__input' 或者 'search-form__content-input' -->
        <input class="search-form__content__input"/>
        <!-- 推荐:'search-form__button' 或者 'search-form__content-button' -->
        <button class="search-form__content__button"></button>
    </div>
</form>

组成部分 一个元素总是另一个元素的一部分,你不应该单独的使用它

# 修饰符

一种用于定义模块和元素的外观,状态和行为的实体。

  • 修饰符的名称描述了它的外观(“多大?”或者“它的主题是什么?”等等—— size_s 或者 theme_islands),它的状态(“它与其他有什么不同?” —— disabled,focused,等等)以及他的行为(“它的行为什么?”或者“它如何响应用户?”——比如 directions_left-top)
  • 修饰符的名字与模块或者元素的名字使用单下划线分隔(_)

使用 从 BEM 的角度,一个修饰符不能脱离模块或元素而被使用。一个修饰符应该改变实体的外观,行为或者状态,而不是替换它。

<!-- 正确的。'search-form' 模块有值为 'islands' 的 'theme' 修饰符 -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Search</button>
</form>

<!-- 不正确的。'search-form' 丢失了 -->
<form class="search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Search</button>
</form>

# 命名

BEM 的命名并无明确的规定,但是可以有一个通用的约定:

.block{}
.block__element{}
.block--modifier{}	

eg:

.site-search{} /* 块 */
.site-search__field{} /* 元素 */
.site-search--full{} /* 修饰符 */
  • .block 代表了更高级别的抽象或组件。
  • .block__element 代表.block的后代,用于形成一个完整的.block的整体。
  • .block--modifier代表.block的不同状态或不同版本。

# 优势

BEM的关键是光凭名字就可以告诉其他开发者某个标记是用来干什么的。通过浏览HTML代码中的class属性,你就能够明白模块之间是如何关联的.使用BEM我们可以获得更多的描述和更加清晰的结构。

# 如何使用

# 什么时候用

大多数情况下都应该使用,BEM最难的部分之一是明确作用域是从哪开始和到哪结束的,以及什么时候使用(不使用)它。随着接触的多了,有了经验积累,你慢慢就会知道怎么用,这些问题也不再是问题著作权归作者所有。

# 什么时候不用

如果某一个东西在很多场合下存在复用,那么一个简单的描述就好,没有必要遵循BEM的规范

# 例子

常规的CSS写法:

.person{}
.hand{}
.female{}
.female-hand{}
.left-hand{}
.person{}
.person__hand{}
.person--female{}
.person--female__hand{}
.person__hand--left{}   

使用BEM应该注意 并不是所有的地方都应该遵循 BEM的规则

# 参考

http://www.w3cplus.com/css/fifty-shades-of-bem.html http://www.w3cplus.com/css/mindbemding-getting-your-head-round-bem-syntax.html http://getbem.com/introduction/ http://cssguidelin.es/#bem-like-naming

陕ICP备20004732号-3