CSS-BEM命名规范,让维护css不在头疼
相信大部分前端工作人员都不太喜欢写CSS
,更不要说修改别人的CSS
的样式了。
本文将简单介绍CSS-BEM
使用规范,让自己/他人维护起CSS
不在头疼。
前言
BEM(块、元素、修饰符)是一种基于组件的 Web 开发方法。其背后的想法是将用户界面划分为独立的块。这使得即使使用复杂的 UI 也能轻松快速地进行界面开发,并且允许重用现有代码而无需复制和粘贴。该笔记将围绕BEM核心模块,块(
block
)、元素(
element
)、修饰符(
modifier
)进行简述。
贴出官方文档以便大家进一步学习: en.bem.info/
Block
可以重用的功能独立的页面组件。在 HTML 中,块由
class
属性表示。
块的特征:
该块名称描述它的目的(“这是什么?” menu
或button
)(“?这是什么样子” -而不是它的状态red或big)。
例:
// A code block
<!-- 正确。`error` 块在语义上是有意义的 -->
<div class="error"></div>
<!-- 不正确。它描述了外观 -->
<div class="red-text"></div>
这确保了重用块或将它们从一个地方移动到另一个地方所需的独立性.
块的嵌套:
- 块可以相互嵌套。
- 可以有任意数量的嵌套层。
// A code block
<!-- `largesse`块 -->
<div class="largesse">
<!-- `header`块 -->
<header class="header">
<!-- 嵌套`logo`块 -->
<div class="logo"></div>
<!-- 嵌套`search -form`块-->
<form class="search-form"></form>
</header>
<!-- `largesse-main` 该组件下关联的main块>
<main class="largesse-main">
<div class="largesse-logo"></div>
<form class="largesse-search"></form>
</main>
</div>
块的应用:
块可以嵌套在任何其他块内。
例如,head
块可以包括徽标 ( logo
)、搜索表单 ( search
) 和授权块 ( auth
)。
Element:
- 不能单独使用。
- 块的复合部分。
元素的特征:
- 该元素的名称描述它的目的(“这是什么?” -
item
,text
等),而不是它的状态(“什么类型的,或者是什么样子呢?” -red
,big
等)。 - 元素全名的结构是
header__title
。 元素名称与块名称用双下划线 (__
)分隔。
例:
<!-- `html` -->
<div class="largesse">
<header class="header">
<!-- `header` 块中的 `header__title` 元素 -->
<div class="header__title">标题</div>
<div class="header__tip">提示</div>
</header>
</div>
<!-- `less+bem` -->
//largesse块
.largesse {
& > header {
//标题样式
display: flex;
align-items: center;
width: 700px;
height: 100px;
//title元素
&__title {
flex-grow: 1;
}
//提示语样式
&__tip {
width: 400px;
}
}
}
元素的嵌套:
- 元素可以相互嵌套。
- 你可以有任意数量的嵌套级别。
- 元素始终是块的一部分,而不是另一个元素。这意味着元素名称不能定义层次结构,例如
block__elem1__elem2
.
例:
完整元素名称的结构遵循以下模式
<form class="search-form">
<div class="search-form__content">
<input class="search-form__input">
<button class="search-form__button">Search</button>
</div>
</form>
错误示范
<form class="search-form">
<div class="search-form__content">
<!-- Recommended: `search-form__input` or `search-form__content-input` -->
<input class="search-form__content__input">
<!-- Recommended: `search-form__button` or `search-form__content-button` -->
<button class="search-form__content__button">Search</button>
</div>
</form>
块名称定义命名空间,它保证元素依赖于块 ( block__elem
)。
例:
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
这种块结构在 BEM 方法中始终表示为元素的平面列表:
<!-- `less+bem` -->
.block {
&__elem1:{
}
&__elem2:{
}
&__elem3:{
}
}
以上css,在下方示例仍可适用,这允许你更改块的 DOM 结构,而无需更改每个单独元素的代码
例:
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block__elem3"></div>
</div>
元素的应用:
不能在块之外使用的块的组成部分。
例如,菜单项不在菜单块的上下文之外使用,因此它是一个元素。
修饰语Modifier
一个 BEM 实体定义了一个块或者元素的外观与行为。
修饰语的使用并不是必须的。
修饰语本质与与 HTML 的属性(attribute
)相似。同样的块因为使用了修饰语而变得不一样了。
比如,菜单块(menu
)外观的改变依赖于他使用的修饰语。
修饰符的特征:
- 用于修饰块或元素,体现出外形行为状态等特征的,可作为一个修饰器
- 保证各个部分只有一级B__E–M,修饰器需要和对应的块或元素一起使用,避免单独使用。
- 避免
.block__el1__el2
的格式。
例:
<!-- `html` -->
<div class="test">
<main class="test-main">
<section class="test-main__content">
<!-- `修饰符与块-元素一起使用,用于标注一种状态/颜色/` -->
<div class="test-main__content--blue">blue</div>
<div class="test-main__content--green">green</div>
<div class="test-main__content--yellow">yellow</div>
</section>
</main>
</div>
<!-- `css` 这里采用的是less-->
.test-main {
&__content {
width: 400px;
height: 400px;
display: flex;
margin: 0 auto;
& > div {
flex-grow: 1;
height: 50%;
text-align: center;
line-height: 200px;
color: #fff;
}
&--blue {
background: rgb(60, 79, 224);
}
&--green {
background: rgb(6, 182, 108);
}
&--yellow {
background: rgb(255, 195, 61);
}
}
}
修饰符的应用:
定义块或元素的外观和行为的 BEM 实体。
例如,菜单块 (menu
)的外观可能会根据其上使用的修饰符而改变。
修饰符可以在运行时更改(例如,作为对块的 DOM
事件的反应),即双向绑定,可用于做表单的错误提示显隐判断。
总结
BEM 难点在于明确节点的作用域,开始和结束,如何正确的使用,科学的使用。
但其实说穿了,BEM保证样式不冲突的核心就是:在元素名中加入唯一的标识。这个标识在BEM中对应的是模块名,也可能是一个独一无二的乱序字符串。