概要
BEM 分别代表着:Block(块)、Element(元素)、Modifier(修饰符),是一种组件化的 CSS 命名方法和规范,由俄罗斯 Yandex 团队所提出。其目的是将用户界面划分成独立的(模)块,使开发更为简单和快速,利于团队协作开发。
特点
组件化/模块化的开发思路。
书写方式解耦化,不会造成命名空间的污染,如:写法带来的潜在嵌套风险。
命名方式化扁平,避免样式层级过多而导致的解析效率降低,渲染开销变大。
组件结构独立化,减少样式冲突,可以将已开完成的组件快速应用到新项目中。
有着较好的维护性、易读性、灵活性。
规则
的命名模式在社区中有着不同方式,以下为 Yandex 团队所提出的命名规则为(本文中的代码使用该规则):
不同的命名模式,区别在于之间的连接符号不同,依个人而定:
任何一种规范,都是基于实际需求而定,便于团队开发和维护扩展,每个规范都是经过合理评估后所得出的一种“思路”和“建议”。
Block(块)
是一个独立的实体,即通常所说的模块或组件。
例:、、
规则
块名需能清晰的表达出,其用途、功能或意义,具有唯一性。
块名称之间用连接。
每个块名前应增加一个前缀,这前缀在 CSS 中有命名空间(如:、、分别代表:、)。
每个块在逻辑上和功能上都相互独立。
由于块是独立的,可以在应用开发中进行复用,从而降低代码重复并提高开发效率。
块可以放置在页面上的任何位置,也可以互相嵌套。
同类型的块,在显示上可能会有一定的差异,所以不要定义过多的外观显示样式,主要负责结构的呈现。
这样就能确保块在不同地方复用和嵌套时,增加其扩展性。
综上所述,最终我们可以把规则最终定义成:
情景
需要构建一个组件。
写法
结构
如果打算开发一套框架,可以使用具有代表性的缩写,用来表示命名空间:Element UI(el-)、Ant Design(ant-)、iView(ivu-)。
Element(元素)
是块中的组成部分,对应块中的子元素/子节点。
例:、、
规则
元素名需能简单的描述出,其结构、布局或意义,并且在语义上与块相关联。
块与元素之间用连接。
不能与块分开单独使用。
块的内部元素,都被认为是块的子元素。
一个块中元素的类名必须用父级块的名称作为前缀,因此不能写成:。
情景
组件中包含和,是列表中的一个子元素。
写法
结构
原则上书写时不会出现两层以上的嵌套,所有样式都为平级,嵌套只出现在,状态激活时的情况。
Modifier(修饰符)
定义块和元素的外观、状态或类型。
例:、、
规则
修饰符需能直观易懂表达出,其外观、状态或行为。
修饰符用连接块与元素。
修饰符不能单独使用。
在必要时可进行扩展,书写成:,第一个表示其命名空间。
情景
假定组件有多种外观,我们选择其中一种。并且在用户未输入内容时,显示为禁用样式。
写法
结构
小结
很多人觉得 写法难看,审美本是“智者见智,仁者见仁”的事。刚刚接触可能是会觉得有点奇怪,但所有东西都有一个适应过程。如果仅仅为了好看,规避其优点,我认为得不偿失。个人建议可以尝试使用 规范来书写代码。
命名会使得 Class 类名变长,但经过 等压缩后,文件的体积其实并无太大影响。
就和早年提出 一样,不要为了语义而去语义,语义化本身的作用就是帮助大家更好的识别代码,所有的规范都是基于项目的发展和团队的协作,团队可以根据成员的意愿选择最合适的方式。
参考资料:
BEM.infoGetBEM.com
BEM-like Naming
‘Why BEM?’ in a nutshell
从 BEM 谈大型项目中 CSS 的组织和管理
爱设计,爱前端,也爱颠覆创新;
爱生活,爱音乐,也爱小资情趣。有点唠叨,也有点感叹。
领取专属 10元无门槛券
私享最新 技术干货