咱们知道,css使用中一个比较使人烦恼的问题,就是css没有做用域可言,咱们写了一个组件或者模块以后,每每但愿它们能够四处复用,可是因为css没有做用域,咱们给样式命名的时候都会很是当心,由于惧怕命名重复致使组件的样式被覆盖。因而,每一个新加入项目的开发者在开发相似已有的组件时,极可能就本身从新命名一份新的样式表,以避免和现有的重复,那么就会致使css文件像滚雪球同样愈来愈大。css
如今市面上有许多旨在减小CSS代码量,且方便程序员合做和维护CSS代码的方案,例如OOCSS、SMACSS、SUITCSS,而BEM是其中最常被人提起的一个方案。html
BEM的本质其实只是一个css命名方案。前端
BEM is a highly useful, powerful and simple naming convention to make your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit and a lot more strict.(BEM是一个很是有用,强大和简单的命名规范,使您的前端代码更容易阅读和理解,更容易使用,更容易扩展,更强大和更明确,更严格。)git
以上是BEM官网的解释,能够知道它就是一个命名方案,那么它的规范是怎样的?为何说它更容易阅读也更容易扩展呢?咱们下面来看看BEM的具体命名规范。程序员
所谓BEM,实际上是三个单词的缩写:Block(模块)、Element(元素)、Modifier(修饰符)。github
一个块是一个独立的实体,就像应用的一块“积木”。一个块既能够是简单的也能够是复合的(包含其余块)。sass
命名规范:less
块名称能够由拉丁字母,数字和短划线组成。 如:.blockide
以下图的搜索框和按钮组成的组件就是一个块。
性能
一个元素是块的一部分,具备某种功能。元素是依赖上下文的:它们只有处于他们应该属于的块的上下文中时才是有意义的。
下图中的input和button都是元素。
命名规范:
元素名称能够包含拉丁字母,数字,破折号和下划线。 CSS类名写成块名称加上两个下划线加上元素名称:.block__elem
修饰符是块或元素上的标志。这些标志用来形容元素或块的外观、行为或状态。例如button、a标签上的active状态。
命名规范:
修饰符名称能够包含拉丁字母,数字,破折号和下划线。 CSS类名写成块或元素的名称加上两个破折号:.block--mod或.block__elem--mod和.block--color-black。
假设您有一个带有修饰符“theme:xmas”和“simple:true”的表单块,而且表单块带有input和submit元素。submit元素带有修饰符“disabled: true”,在未填充表单时禁止提交表单。
HTML
<form class="form form--theme-xmas form--simple"> <input class="form__input" type="text" /> <input class="form__submit form__submit--disabled" type="submit"/> </form>
CSS
.form { } .form--theme-xmas { } .form--simple { } .form__input { } .form__submit { } .form__submit--disabled { }
从上面的实例中,咱们不难发现BEM有如下特色:
试想,BEM的命名规范这么长,若是咱们本身手写那么长的类名,那非得累死不可。所以借助一些如less、sass的预处理器来帮忙,能够提高咱们的开发效率。
以less为例,咱们可使用&符简化咱们的代码:
.form { width: 12rem; height: 6rem; &__input{ font-size: 16px; } &__submit{ background: blue; &--disabled{ background: gray; } } }
编译后:
.form { width: 12rem; height: 6rem; } .form__input { font-size: 16px; } .form__submit { background: blue; } .form__submit--disabled { background: gray; }
1.命名并不是那么死板
实际上,不少团队在应用BEM的时候,都根据本身的业务做了必定的调整,好比Instagram团队使用的驼峰式: .blockName-elementName--modifierName { /* ... / },还有单下划线:.block-name_element-name--modifierName { / ... */ }。因此不用那么严格遵照,可根据本身的须要来变化。
2.修饰器的写法有可改进之处
有时候元素的状态须要js来控制,此时遵循BEM规范没有任何好处,好比激活状态,BEM推荐的写法是:
.block__element { display: none; } .block__element--active { display: block; }
这样就须要咱们知道block__element的名称,并且类名也会变得很长,并且active类的样式也没法复用,所以咱们能够考虑用常规的操做增长例如.js-active或.is-active这样的类名来控制。
.block__element { display: none; } .block__element.is-active { display: block; }
3.每一个block能够单独一个css
因为BEM规范下产出的css独立性高,所以能够考虑每一个组件单独一个css,当某个页面须要某个组件时,是须要把这个组件的css @import 到页面的css中便可。
/* page.css */ @import "form.css"; @import "slider.css"; .block__element { display: none; }
参考:
使用案例: