前言
前端开发无论web还是h5都会涉及各种规范,脚手架使用规范、目录规范、命名规范、文档规范、流程规范等等,本文主要针对前端命名规范中dom元素类名(className)的命名规范提出个人的一些想法,希望能给读者带来帮助或启发。
主流命名规范
1. OOCSS
Object-Oriented CSS,示例:
<div class="sizeOne bgBlue solidGray"></div>
.sizeOne {width: 25%;}
.bgBlue {background:blue;}
.solidGray {border: 1px solid #ccc;}
oocss的核心原则:
- 独立的结构和样式
- 独立的容器和内容
其优点:
- 减少CSS代码
- 具有清洁的HTML标记,有语义的类名,逻辑性强的层次关系
- 语义标记,有助于SEO
- 更好的页面优化,更快的加载时间(因为有很多组件重用)
- 可扩展的标记和CSS样式,有更多的组件可以放到库中,而不影响其他的组件
- 能轻松构造新的页面布局,或制作新的页面风格
其缺陷:
- OOCSS适合真正的大型网站开发,因为大型网站用到的可重用性组件特别的多,如果运用在小型项目中可能见不到什么成效。所以用不用OOCSS应该根据你的项目来决定。
- 如果没用巧妙的使用,创建组件可能对于你来说是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定还是个维护的噩梦。
- 最好给每一个组件备写一份说明文档,有助于调用与维护
参考链接:www.w3cplus.com/css/oocss-c…
2. SMACSS
3. SUITCSS
4. Atomic
参考链接:www.geeksforgeeks.org/introductio…
5. BEM
Block、Element、Modifier,BEM是我目前在使用的命名方式,也是本文重点要讲述的,基于BEM的规范制定了一套符合业务、框架以及开发模式的规范。首先简单介绍下BEM,详细内容可查看参考链接。
Block
独立的有意义的实体,eg:
header、container、menu、checkbox、input、footer等,它是在整个页面布局时,划分的单独模块。
Element
元素,是Block下的子元素,其没有独立的意义,但属于Block的一部分,eg:
menu item、 list item、 checkbox caption、 header title
Modifier
Block或Element上的标志标识,用来改变外观、状态、行为、标记等,eg:
disabled、 highlighted、 checked、 fixed、 size big、 color yellow
我的命名规范
基于BEM,我进行了扩展,我认为项目名也可以是一个Block,而项目旗下的页面,组件都可以视为block下的元素element,项目是独立的实体,组件、页面是其的一部分,page、component等是他的标识modifier,该概念完全符合BEM的设计理念,也比较适用于我们项目开发。
在我们使用vue、react或者angular开发业务时,势必会涉及到这几个概念:
- 页面级组件;
- 全局通用组件;
- 模块内通用组件;
- 页面独有的组件;
针对这些场景,我们如何命名区分,达到通过类名就能大致了解组件的用途,甚至自注释,同时也能有效的防止命名重复导致的样式冲突呢?
1. 页面级组件
路由所对应的页面,也称为页面级组件。
<页面>--page 必要时候 可以带上项目缩写:<项目缩写>__<页面>--page
eg:
外层页面目录:my-order;
页面:我的订单;
命名:my-orders--page;
2. 全局通用组件
全局通用的组件,适用于不同模块下的多个页面。
<组件名>--global-component
必要时,为了防止命名冲突可以带上项目简写:
<项目缩写>__<组件名>--global-component
eg:
全局组件存放路径:src/components
通用组件:按钮组件
命名:button--global-component
3. 模块内通用组件
模块内多个页面都要用到的组件,我将它称之为模块内通用组件,通常存放在一级路由文件夹下的components下,例如/src/pages/personal-center/components。
<组件名>--module-component
必要时,为了防止命名冲突可以带上项目简写:<项目缩写>__<组件名>--module-component
eg:
存放路径:/src/pages/personal-center/components
模块内通用组件:弹窗组件
命名:modal--module-component
4. 页面独有组件
仅适用于当前页面的组件,我将它称之为页面独有组件。
<组件名>--component
eg:
存放路径:/src/pages/personal-center/my-order/components模块内通用组件:标签组件
命名:tag--component
modifier新增四种:page、global-component、module-component、component。
组件名、模块名、页面名称都使用 ‘-’ 连接,eg:record-item、award-detail。
以上的命名都是针对组件容器的class命名,那么组件内部的子元素该如何命名呢?
1. 统一前缀命名
所有子元素都使用统一的前缀去命名,eg:button__text。
该方法的缺点,如果组件名称长,看着不优雅,很多重复,若使用变量定义,eg:
const classPrefix = 'tpc_datetime-picker'
<div className={`${classPrefix}__title`} />
这么写的话,总感觉也不是特别优雅,但也还在接受范围。
2. 使用组件名前缀
使用组件名称,去除项目简写,eg:button--disabled
针对子元素内部的命名,eg:button__label--warning
在组件开发过程中,建议可以将前缀使用变量保存,css也是。如此去命名你的class,既明了,又能防止命名重复导致样式冲突,让每一个类变得更有意义。可能有的前端比较反感命名长,喜欢用简短的命名,可以适当调整类名的前缀,让class不显得过长,如此命名,防重复,类名可读性很高,会让你的业务更清晰,html的结构层次也更明了。