前言
在大型前端项目中,CSS的维护和管理一直是一个重要课题。为了使用CSS的开发更加规范,目前有很多流行的命名方法尝试在选择器命名上解决以下问题:
- 减少大型项目中CSS占用的空间
- 提高程序员间的协作效率
- 简化CSS代码库的维护工作
- 理清CSS的继承关系
- 提高代码的可读性和可维护性
- 避免样式冲突和污染
本文将对BEM(Block Element Modifier)命名规范进行深入介绍,并通过实战案例进行详细剖析
BEM(Block,Element,Modifier)
关于BEM
新手小白在写CSS的时候一定在命名上有很多困扰。我们都知道命名需要做到“见名知义”,但是如果组件层级关系和样式一多,就会带来命名相同、关系不清楚等的问题,又很苦恼。了解了BEM这个规范你将变得清晰明了。
什么是BEM?
BEM (Block, Element, Modifier)是由俄罗斯重要门户网站Yandex(类似于百度、谷歌等)的开发团队提出的一种CSS命名方法论。
来自BEM官方网站 (getbem.com)对BEM的定义:
BEM —— is a methodology that helps you to create reusable components and code sharing in front‑end development.
BEM —— 是一种帮助您在前端开发中创建可重用组件和代码共享的方法。
现在有许多国际大型企业都在使用BEM开发网页,除了在BEM官网中罗列的JetBrains,国内还有微信也在使用这一CSS命名方法。
BEM的核心思想
BEM的核心思想是 将页面拆分成一个个独立的富有语义的块(blocks)。 学习BEM主要就是学习它的命名层级与命名约定。
命名层级
BEM命名包含三个核心概念:
-
Block(区块):
- 独立的、可复用的组件
- 可以包含其他Block
- 例如:header、menu、form等
-
Element(元素):
- Block的组成部分
- 不能脱离Block独立存在
- 例如:menu__item、form__input等
-
Modifier(修饰符):
- 定义Block或Element的外观、状态或行为
- 例如:button--primary、menu__item--active等
命名约定
BEM的命名规范非常严格,具体如下:
-
Block命名:
- 使用小写字母
- 单词之间用单短线(-)连接
- 例如:
header、menu、form
-
Element命名:
- 以Block名称为前缀
- 使用双下划线(__)连接
- 例如:
header__logo、menu__item
-
Modifier命名:
- 以Block或Element名称为前缀
- 使用双连字符(--)连接
- 例如:
button--primary、menu__item--active
BEM 实战
WeUI组件预览页面
这是一个微信WeUI中Button组件的预览页面,你也可以点击访问 WeUI组件预览-Button 一同领略其源码中的BEM命名法。
但这个页面源码中,只参考了BEM的命名层级,其命名约定采用了团队内部的法则,与BEM不完全相同。
为了大家能够对原始的BEM命名规范有深刻的了解,本文将会重新编写完全遵守BEM的代码来完成这个页面。
这个页面结构很简单,我们可以先为整个页面划分好布局: 定义整个页面命名为page的Block,而下面的按钮和中间的操作可划分为Block下的Element,可以定义为page__hd和page__bd。 代码为:
<body>
<!-- block -->
<div class="page">
<!-- element -->
<div class="page__hd"></div>
<div class="page__bd"></div>
</div>
</body>
<body>
<!-- block -->
<div class="page">
<!-- element -->
<div class="page__hd">
<div class="page__title"></div>
<div class="page__desc"></div>
</div>
<div class="page__bd"></div>
</div>
</body>
按钮部分代码为:
<!-- 主要按钮 -->
<a href="#" class="button button--primary button--loading">主要操作</a>
<a href="#" class="button button--primary button--disabled">主要操作</a>
<!-- 默认按钮 -->
<a href="#" class="button button--default">次要操作</a>
<a href="#" class="button button--default button--loading">次要操作</a>
<a href="#" class="button button--default button--disabled">次要操作</a>
<!-- 警告按钮 -->
<a href="#" class="button button--warn">警示操作</a>
<a href="#" class="button button--warn button--loading">警示操作</a>
<a href="#" class="button button--warn button--disabled">警示操作</a>
给出的demo: