Open FridaS opened 6 years ago
BEM介绍 2018年04月02日
前两天腹肌哥哥抱怨我们的样式文件杂乱而难以维护时提到了BEM,于是决定对其一窥究竟。
BEM自称前端开发方法论(Frontend Development Methodology),提供了包括命名规则、CSS/JS模块化原则、构建工具在内的一套用于开发环节的方法。这篇文章只讨论其在CSS class name命名上的规范。
按照BEM的官方说明,
BEM是一种非常有用的、强大的、简单的命名规范,它使你的前端代码具有更高的可读性、更易于使用、更容易扩展、更健壮、更明确、更严格。
BEM代表 块(block)、元素(element)、修饰符(modifier),它们被称为BEM实体。
块是本身具有意义的独立实体。在大多数情况下,任何独立的页面元素都可以被视作一个块。比如header、container、menu、checkbox、input。
header
container
menu
checkbox
input
块可以包含其他块。比如,下图中的header块包含了logo块、navigation块和search块。
比快更细粒度的是元素(element)。
元素是块的组成部分,它表现为某一特定的功能。元素依赖块而存在、它只在其所属的块的上下文中有意义(脱离块就不能使用)。比如menu块的item元素、header块的title元素。
item
title
下图中,一个search块包括text input元素和search button元素。
一个“修饰符”可以理解为一个块或一个元素的特定状态,我们使用它来定义块或元素的不同的外观及行为。
举个例子来理解下:一个button块有两种颜色:红色和绿色,那么就可以定义两个修饰符:red和green,得到的完整的class name就是button--red和 button--green。
red
green
button--red
button--green
BEM方法论提出者Yandex的命名规则:
property-editor
menu__item
menu__item_selected
order_status_paid
BEM并没有限定必须使用怎样的命名规则,目前比较流行的是由Harry Roberts提出的命名规范(也是Google的Material Design Lite库使用的命名规则),其与Yandex规则的不同之处有:
使用由Harry Roberts提出的命名规范
<ul class="menu"> <li class="menu__item menu__item--selected">Menu Item 1</li> <li class="menu__item">Menu Item 2</li> <li class="menu__item">Menu Item 3</li> </ul>
.menu{ list-style: none; } .menu__item{ font-weight: bold; } .menu__item--selected{ color:red; }
BEM的优点:
BEM特色的关键是块的相互独立,具有高度的可移植性和可复用性;
在BEM命名规则中,所有的CSS样式规则都只用一个类别选择器,因此所有样式规则的特异性(specificity)都是相同的,也就不存在复杂的优先级问题;
防止CSS嵌套过深;
每个CSS类名都很简单明了,可读性非常高;
类名的层次关系可以与DOM节点的树形结构相对应,读HTML结构时,能很容易地看出元素之间的依赖关系;
减少了类名冲突和副作用的可能性,没有如.mod-xxx ul li 的写法带来的潜在的嵌套风险。
.mod-xxx ul li
我在haitaowap工程上随意找了一段代码:
其样式为:
现在按照BEM改写它:
<div class="n-inGroupBuyShare"> <ul class="dialogs"> <li class="product"> <div class="head"> <img class="head__img" src="${headImg!''}" alt=""> </div> <div class="content"> <img class="content__img" src="${imageUrl!''}" alt=""> <p class="content__desc">${goodsTitle}</p> <p class="content__price">¥<em class="content__actual-price">${groupBuyPrice}</em></p> </div> </li> </ul> </div>
.head__img, .content__img{ width: 444px;height: 446px; } .content__desc{ margin-top: 7px;margin-bottom: 9px;height: 111px;overflow: hidden; font-size: 26px;line-height: 37px;font-weight: bold; } .content__price{ display: flex; height: 50px; align-items:center; font-size: 28px;color: #e31436; } .content__actual-price{ margin-left:-4px; font-size:52px;font-style:italic;margin-top:-13px; letter-spacing:1px;font-weight:bold; -webkit-font-smoothing: antialiased;text-rendering: optimizeLegibility; }
当然,有很多人不喜欢使用BEM,他们认为:
BEM并不能完美地解决所有的问题,但是其思想可以借鉴:
如果认为其命名冗长不可取,那么完全可以取其精华、去其“糟粕”。
by Frida
依稀记得BEM2017年初就讨论过, 当时是子龙在做 kmui 的过程中提出来的, 然后就没有然后了...
BEM介绍 2018年04月02日
前两天腹肌哥哥抱怨我们的样式文件杂乱而难以维护时提到了BEM,于是决定对其一窥究竟。
BEM自称前端开发方法论(Frontend Development Methodology),提供了包括命名规则、CSS/JS模块化原则、构建工具在内的一套用于开发环节的方法。这篇文章只讨论其在CSS class name命名上的规范。
按照BEM的官方说明,
BEM实体
BEM代表 块(block)、元素(element)、修饰符(modifier),它们被称为BEM实体。
块是本身具有意义的独立实体。在大多数情况下,任何独立的页面元素都可以被视作一个块。比如
header
、container
、menu
、checkbox
、input
。块可以包含其他块。比如,下图中的header块包含了logo块、navigation块和search块。
比快更细粒度的是元素(element)。
元素是块的组成部分,它表现为某一特定的功能。元素依赖块而存在、它只在其所属的块的上下文中有意义(脱离块就不能使用)。比如
menu
块的item
元素、header
块的title
元素。下图中,一个search块包括text input元素和search button元素。
一个“修饰符”可以理解为一个块或一个元素的特定状态,我们使用它来定义块或元素的不同的外观及行为。
举个例子来理解下:一个button块有两种颜色:红色和绿色,那么就可以定义两个修饰符:
red
和green
,得到的完整的class name就是button--red
和button--green
。命名规则
BEM方法论提出者Yandex的命名规则:
property-editor
;menu
,该快中的元素的CSS类名都会包含menu作为前缀;menu__item
;menu__item_selected
,其中selected是不二修饰符;名值对修饰符由名称和值两部分组成,通过单个下划线(_)分隔,如order_status_paid
对应 status 为 paid 的订单;BEM并没有限定必须使用怎样的命名规则,目前比较流行的是由Harry Roberts提出的命名规范(也是Google的Material Design Lite库使用的命名规则),其与Yandex规则的不同之处有:
使用由Harry Roberts提出的命名规范
为什么要用BEM
BEM的优点:
BEM特色的关键是块的相互独立,具有高度的可移植性和可复用性;
在BEM命名规则中,所有的CSS样式规则都只用一个类别选择器,因此所有样式规则的特异性(specificity)都是相同的,也就不存在复杂的优先级问题;
防止CSS嵌套过深;
每个CSS类名都很简单明了,可读性非常高;
类名的层次关系可以与DOM节点的树形结构相对应,读HTML结构时,能很容易地看出元素之间的依赖关系;
减少了类名冲突和副作用的可能性,没有如
.mod-xxx ul li
的写法带来的潜在的嵌套风险。我在haitaowap工程上随意找了一段代码:
其样式为:
现在按照BEM改写它:
争议
当然,有很多人不喜欢使用BEM,他们认为:
总结
BEM并不能完美地解决所有的问题,但是其思想可以借鉴:
如果认为其命名冗长不可取,那么完全可以取其精华、去其“糟粕”。
参考文章
by Frida