# 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