1.1. 命名规范的意义
该命名规范主要解决以下问题:
- 从类名可以清晰区分出其功能作用,使页面结构清晰【命名空间、标识符】;
- 以组件、模块的思想去写一个区块的结构,强化结构的模块化【BEM模块思想、基类、子类、扩展类】;
- 减少多人合作、项目耦合等情况下的命名冲突【命名空间】;
1.2. 命名规范思想
【强制】 区块、模块、组件等一个整个的结构遵循BEM命名思想;
当你能确定组件内最后一级的结构不会再发生变化时,最后一级可省略类名,使用两层嵌套;
.type代表了命名空间;.block代表了当前业务内高级别的抽象或组件;.block_element代表.block的后代,用于形成一个完整的.block的整体;.block_element__childerElm代表 element的后代(两层选择器嵌套)
相关链接:
1.3. BEM 命名约定
使用 BEM 命名规范
BEM代表 “块(block),元素(element),修饰符(modifier)”,我们常用这三个实体开发组件。
··.type-block__element__childerElm--modifier··在选择器中,由以下三种符号来表示扩展的关系
| 符号 | 名称 | 解释 | 备注 |
|---|---|---|---|
| ----------------------------------------------------------------------------------------------------- | |||
-|
单中划线|
仅作为连字符使用,表示业务缩写与业务模块之间的连接记号| <br/> | |||
|---|---|---|---|
-- | 双中划线|
双中划线用来描述一个块或者块的子元素的一种状态(特定属性)| <br/> |
|
__ | 双下划线|
双下划线用来连接块与元素(在深度嵌套时允许元素与元素 但是只能嵌套两层)| <br/> |
|
_ | 单下划线|
单下划线用来链接块与元素| 移除 |
我们有两种个方法来标识当前块或者是块元素以及块子元素的一种状态 分别是以下两种选择 独立的状态钩或者是一个在组件级BEM方式命名的修饰器。
独立状态勾
// .is- 或 .has- 这种书写形式代表修饰符 在选择器中我们搭配组件的节点使用`.block.is-active.block .is-active` |
|---|
// --modifier 这种书写形式也代表修饰符,使用双中划线--直接在我们当前节点的类名中使用`.type-block__element--modifier` |
|---|
type(命名空间)
命名空间 是代表布局 代表组件 代表状态; 对于命名空间的解释会在下方提到;在大多数情况下,业务内的独立页面元素上的class命名 都会在前面加上该特定的命名空间,这个前缀可以保证不同的项目 不会出现命名上的冲突。当然我们组件化开发 并非是必须要添加这个前缀。block(块)
一个块是业务中独立页面的元素,这个元素或是某个布局的一部分。在大多数情况下,任何独立页面元素 都可以被视为一个块。它的HTML容器会有一个唯一的CSS类名,也就是这个块的名字。针对这个块的定义 我有个基本原则: 每个块名都应该有一个type (命名空间) 元素(element)
元素是块的组成部分,不能脱离块使用。块中的子元素是块的子元素,并且子元素的子元素在bem规范中也被认为是块的直接子元素。元素可以互相嵌套,并且可以嵌套任意数量。但是元素只能是块的一部分,命名不能嵌套超过与两层。也就是命名层级不能是block__elm1__elm2__elm3 ,不允许再往下嵌套.一个块中元素的类名必须用父级块的名称作为前缀!如下例子;例1
// 常规写法`.list{}.list .item{]// bem写法.list {}.list__item{}` |
|---|
例2
// 在css中不需要跟block一起使用,而是独立定义规则。这样,当修改block结构时 不需要修改css.`<!DOCTYPE html> <head> <style` `type="text/css"> .block {} .block__elem1 {} .block__elem2 {} .block__elem3 {} </style> </head> <body> <div` `class="block"> <div` `class="block__elem1"> <div` `class="block__elem2"> <div` `class="block__elem3"></div> </div> </div> </div> // 块的结构改变了,但是元素及其名称的规则保持不变。 <div` `class="block"> <div` `class="block__elem1"> <div` `class="block__elem2"></div> </div> <div` `class="block__elem3"></div> </div> </body></html`> |
|---|
修饰符(modifier)
一个修饰符 可以理解为一个块或者是元素的特定状态(选中 打开 ...),标识着它持有一个特定的属性。用一个例子来解释。一个按钮的块默认有三个大小:小,中,大。为了避免创建三个不同的块,我们可以为这些不同的块加上不同的修饰符。这个修饰符应该有个名字(比如:size)和值(small,normal,large);如下例子:// 常规写法`.button{}.button .small{].button .normal{].button .large{]// bem写法.button {}.button--small{}.button--normal{}.button--large{}` |
|---|
1.3.1. 多单词之间链接
所有的多单词是用小写驼峰式命名,不允许使用中划线或者是下划线链接多个单词;
多个单词使用小写驼峰式命名,以提升名称的识别度。例如: newList;
1.4. BEM 命名空间
在合适的地方使用命名空间
- 布局: 以l为命名空间 例如: .l-warp、.l-header、.l-content、.l-main、.l-aside 等;
- 工具: 以u为命名空间 例如: .u-clearfix、.u-ellipsis等;// 表示不耦合业务逻辑的、可复用的的工具
- 状态: 以is为命名空间 例如: .is-open、.is-active、.is-selected 等; // 表示动态的、具有交互性质的状态
- 组件: 以c为命名空间 例如: .c-slider、.c-dropMenu 等; // 表示可复用、移植的组件模块
- 扩展: 以ext为命名空间 例如: .ext-cover、.ext-alignLeft 等; //表示对组件的视觉形态的扩展
状态类和扩展类 不允许单独使用 必须搭配节点来使用。举个例子,同一个页面有可能会在不同的地方使用is-active,并且每个is-active操作的节点是不同的,所以需要使用.c-button.is-active或.c-button–active 等方式来定义。
1.5. 命名风格
1.5.1.1. 书写原则
- 原则上不会出现两层以上的选择器嵌套
- 两层选择器嵌套出现在.c-box__item__current子元素情况下,如下:
使用推荐的嵌套写法
常规写法:
.c-radio{}`.c-radio__label{}.c-radio__label__span{}// 嵌套写法`.c-radio__label__span .c-radio__link{} |
|---|
推荐写法
.c-radio{}`.c-radio__label{}.c-radio__label__span{}// 嵌套写法.c-radio__label__span { .c-radio__link {}}` |
|---|
1.5.1.2. 组成元素
- 命名必须由单词 或 数字组成 多单词之间使用小驼峰形式命名不允许使用中划线和下划线链接单词;
- 不允许使用拼音(约定俗成的除外,如youku,baidu),尤其是所写的拼音、拼音与英文的混合!
不推荐
.xiangqing { sRules; }`.news_list { sRules; }`.zhuti { sRules; } |
|---|
推荐
.detail { sRules; }`.news-list { sRules; }`.topic { sRules; } |
|---|
1.5.1.3. 词汇规范
- 不依据表现形式来命名
- 可根据内容来命名
- 可根据功能来命名
- 命名需要与数据 等 方面有耦合性
不推荐
left, right, center, red, black |
|---|
推荐
nav, aside, news, type, search |
|---|
1.5.1.4. 缩写规范
- 保证缩写之后还能较为清晰的保持原单词所能表述的意思
- 使用业界熟知的或约定俗成的
不推荐
navigation => navi`header => head`description => des |
|---|
推荐
navigation => nav`header => hd`description => desc |
|---|