博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于css命名的一点思考,探讨一下css命名空间的可行性
阅读量:6721 次
发布时间:2019-06-25

本文共 3242 字,大约阅读时间需要 10 分钟。

本文主要是探讨传统项目中的css命名,vue、react等单页应用都可以使用css-module来解决这个问题

作为一名初级前端,免不了要切图(写css、html静态部分),写css最头痛的就是给class命名了,词汇有限,本人又比较懒,想类名比布局还费劲。在网上找了一通,到是有比较统一的,接受度较高的。但css命名似乎没有什么比较完美的方案。

简洁法

张鑫旭大神的简洁法是这样的:

.fr {    float: left;}.tc {    text-align: center;}.pb8 {    padding-bottom: 8px;}

简洁法重用率高,性能好,但是这么一堆class,有点写行内式样的感觉了,维护起来太难受了。毕竟这是张鑫旭七年前的文章。

BEM命名法

BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。BEM命名约定更加严格,而且包含更多的信息,它们用于一个团队开发一个耗时的大项目。 ————摘自大漠老师BEM科普

BEM应该算是比较科学比较系统的命名法了,每个class都BEM来一套,自然不会混乱。但是这冗长的类名写起来,真让人手软。虽然用scss的&选择器可以省不少事,不过html里的冗长类名还是免不了,pug等html模板也救不了我们啊。

于是我在想有没有一种既科学又简洁的css命名法呢,于是我自创了一种命名空间法,在自己项目里用的倒挺开心。但此法没有经过大型项目的考验,希望大神们来探讨一下可行性。

命名空间法

基本思想

此法配合scss使用更佳哦,思想就是在最外层使用独特的模块命名,在内层使用简单的类名,禁止在最外层使用简单的类名,不同的模块之中,可以任意使用简单的类名,并不影响其他模块。

举个例子:

.m-header {    .left {        background: red;        height: 10px;    }    .right {        background: yellow;        height: 10px;    }}.m-body {    .left {        background: blue;        height: 10px;    }    .right {        background: green;        height: 10px;    }}

结果是这样的:

html

不了解scss的同学可以看一下编译后的css:

.m-header .left {  background: red;  height: 10px; }.m-header .right {  background: yellow;  height: 10px; }.m-body .left {  background: blue;  height: 10px; }.m-body .right {  background: green;  height: 10px; }

两个模块(m-header和m-body,模块推荐以m-为前缀)中的.left和.right互不影响,只要我们在最外层定义一个独特的类名,如同命名空间,并且不在最外层使用简单类名,防止冲突。那么我们就可以再模块内部随意使用各种类名,当然下个模块内可以再用一次,妈妈再也不担心我词汇量不足了,想不出名字了。

.top, .bottom, .left, .right上上下下左右左右baba一套又一套。为了规范推荐使用更加语义化的类名,当然不必带上长长的前缀。

公用式样

一个项目里可能会有很多公共式样,其实只要我们遵循一点规范便不会发生冲突。比如公共式样我们统一带上'p-'前缀。其它地方你就别用'p-'做前缀了。scss里的mixin、function、$variable我们也可以用起来,提高效率。

.p-btn {    font-size: 14px;}.p-bg-green {    background: green;}

 嵌套过深的问题

很多css规范里都规定嵌套不能超过四层,下面这个例子里我们已经嵌套6层了。在scss里我们不能直接使用@at-root这会将简单类名暴露到最外层。使用&也不能避免嵌套过深。

这时我们需要使用@at-root 后面写上模块名空格即可防止嵌套过深,并避免式样污染了。嵌套特别深的情况下推荐启用子模块。(这里可能存在漏洞,不知道大神们有没有更优雅的方案)

.m-header {    .a {        background: #000;        .b {            background: #111;            .c {                background: #222;                @at-root .m-header .d {                    background: #333;                    .e {                        background: #444;                    }                }            }        }    }}

编译成css:

.m-header .a {    background: #000;}.m-header .a .b {    background: #111;}.m-header .a .b .c {    background: #222;}.m-header .d {    background: #333;}.m-header .d .e {    background: #444;}

使用子代选择器让命名更随意

如果你不用兼容老掉牙的ie6,对于一些只在子代中生效的式样(大多如此),带上子代选择器吧。多敲一个>,优点是css渲染效率更高,命名可以更佳随意,你甚至可以这样,虽然不推荐。

.m-header {    > .a {        height: 40px;        background: red;        > .a {            height: 20px;            background: green;        }    }}

式样并没有冲突:

html2

总结一下命名空间法规范

  1. 最外层css模块m-为前缀,并且类名独一无二。
  2. 模块内元素式样通过后代或子代选择器约束,只作用与此模块,使用简洁的语义化命名。
  3. 公共式样使用p-为前缀。
  4. 禁止在最外层使用简单的类名,可增加特定前缀,防止污染模块内式样。

此方法与很多编程语言的命名空间有着异曲同工之妙,大家应该看到了私有变量和全局变量的味道。在下经验尚浅,不知道此法有没有大的漏洞,欢迎大家理性讨论,指出问题或加以完善。

补充

自己用了一段时间,如果不是非常复杂的项目(如评论区大神所说的动态css和动态dom)问题不大。有几点感觉需要改进一下:

第一,为了避免嵌套过深和便于复用维护,模块内部不要使用嵌套了,用scss写到第二级就好
第二,父子选择器还是不要用了,因为dom父子关系经常会变动,模块内部css命名推荐用唯一的。

这种方法的确有很多人在用,比如网易的,我发誓之前没有看过 :)逃了

转载地址:http://yjjmo.baihongyu.com/

你可能感兴趣的文章
TCP报文结构
查看>>
架构组织形式的讨论,以及架构师之路的建议
查看>>
详解JavaScript模块化开发
查看>>
C之有符号与无符号(二)
查看>>
DOCKER网络代理设置
查看>>
实习心得体会
查看>>
javascript基础语法——变量和标识符
查看>>
Java静态变量、非静态变量、成员变量、的区别
查看>>
数据库中有外键时JavaBean的写法
查看>>
linux-sed
查看>>
16.4-16.8 Tomcat监听80端口,Tomcat的虚拟主机,访问日志
查看>>
app客户端测试
查看>>
nodejs渐入佳境[23]-hash函数
查看>>
Big Data Integration with Hadoop: A Q&A Spotlig...
查看>>
【062有新题】OCP 12c 062出现大量之前没有的新考题-16
查看>>
触手TV下载|触手TVapp下载
查看>>
PDF文件如何修改,PDF怎么添加文本高亮
查看>>
个人学习分享
查看>>
2019年4月份整理的Unity3D 20个实用插件-免费下载
查看>>
达飞控股不断践行新时代企业责任
查看>>