Why use it
近几年web应用的发展能够用疯狂来形容,依靠浏览器的支持以及前端技术和框架的发展,不少应用已经把大量的逻辑从服务器端迁移到了浏览器端,使用先后端分离技术,浏览器端与用户进行交互来完成复杂的逻辑。因为这个发展趋势,Web应用的前端代码的复杂度大大提升,尤为是 JavaScript 和 CSS 代码的数量大幅增长,面对空前庞大的css和js代码量,造成科学的代码组织方法和命名规范迫在眉睫。css
好的命名规则应该知足如下几个优势:html
- 安全的命名,不会干扰其它css
- 我须要很快知道一个 class 位于这个伟大工程的什么位置
- class 尽量少,且结构清晰
- 嵌套不能够太深,不然会造成难以维护的“谜”之样式
BEM
BEM 是一种前端项目开发的方法学,由 Yandex 公司提出。BEM 的名称来源于该方法学的三个组成部分的英文首字母,分别是块(Block)、元素(Element)和修饰符(Modifier)。这三个不一样的组成部分称为 BEM 实体。前端
Block——块
块便是一般所说的 Web 应用开发中的组件或模块。每一个块在逻辑上和功能上都是相互独立的。块中封装了组件相关的 JavaScript、CSS 代码和 HTML 模板。因为块是独立的,能够在应用开发中进行复用,从而下降代码重复并提升开发效率。块能够放置在页面上的任何位置,也能够互相嵌套。web
Element——元素
元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其余元素。后端
Modifier——修饰符
修饰符用来定义块或元素的外观和行为。一样的块在应用不一样的修饰符以后,会有不一样的外观。浏览器
// 简单地说 .block { /* styles */ } .block__element { /* styles */ } .block--modifier { /* styles */ }
举个栗子
如何使用呢BEM命名方法呢?请先看如下例子:sass
//咱们要为这个菜单写样式 <ul class=""> <li class="">Menu Item 1</li> <li class="">Menu Item 2</li> <li class="">Menu Item 3</li> </ul>
1.“祖传”命名
放在之前,咱们或许会这么写:安全
<ul class="nav"> <li class="item selected">Menu Item 1</li> <li class="item">Menu Item 2</li> <li class="item">Menu Item 3</li> </ul>
看了一下,仍是多清爽的。可是各位朋友是否注意到了一个问题:子元素item和其父元素menu,从命名上看,关系彷佛太不紧密。一个box也能够有item子类,一个xxx也能够包含一个item子类。看看其样式的写法:服务器
//sass .nav { list-style: none; .item { font-weight: bold; &.selected { color: red; } } } //编译后产生的css .nav { list-style: none; } .nav .item { font-weight: bold; } .nav .item.selected { color: red; }
从样式文件上看,仿佛也没有太大问题,可是,这是在咱们代码层数较少的状况。若是是一个复杂的页面元素,咱们sass层级会很是深。编译后的css,层级也会很深。框架
2.BEM命名
如今咱们使用BEM再来编写看看:
<ul class="nav"> <li class="nav__item nav__item--selected">Menu Item 1</li> <li class="nav__item">Menu Item 2</li> <li class="nav__item">Menu Item 3</li> </ul>
//sass .nav { list-style: none; &__item { font-weight: bold; &--selected { color: red; } } } //使用sass编译后的css是 .nav {//菜单 list-style: none; } .nav__item {//菜单item font-weight: bold; } .nav__item--selected { //被选中的菜单item color: red; }
乍看之下,根据 BEM 命名规则产生的 CSS 类名都会很复杂,但实际上在熟悉了命名规则以后,能够很容易理解其含义。其次,css再也不存在复杂的层级关系,浏览器渲染的时候,样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其余选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者由于不匹配而退出,减小层级就能提高性能,对应静态css文件大小也会减小。
不少人会吐槽两个下划线和两个横杠做为链接符,并不优雅。可是我以为,BEM是一种思想,是咱们须要理解的,至于咱们用什么样的链接符,什么样的方式实现,能够根据本身项目的状况考虑。