精简高效CSS命名之“三无原则”
“三无原则”:无ID,无层级,无标签
原因:
- 限制重用
- CSS文件大小
- 降低了渲染效率。
CSS渲染元素和使用JavaScript获取页面元素(先id获取,再tag获取)那是完全不一样的。CSS的渲染方式是“从右往左”渲染的,就拿#test ul{}举例,先渲染页面上所有的ul标签,再去寻找id为test的元素.
CSS命名,只要出现了层级,出现了标签,就是一次额外的渲染,层级越多,渲染的开销也就越大.CSS常用命名规范:
OOCSS,SMACSS,BEM,SUIT
这些规范为我们提供了避免命名冲突的方法并提供了一套可用的作用域规则。
BEM
BEM:block:块,Element:元素,Modifier:修饰符,是由一种前端命名方法论(CSS命名规范)。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。
BEM是一种命名方法,能够帮助你在前端开发中实现可复用的组件和代码共享。
理想的状态下,我们开发一套组件的过程中,我们应该可以随意的为其中元素进行命名,而不必担心它是否与组件以外的样式发生冲突。
BEM解决这一问题的思路在于,由于项目开发中,每个组件都是唯一无二的,其名字也是独一无二的,组件内部元素的名字都加上组件名,并用元素的名字作为选择器,自然组件内的样式就不会与组件外的样式冲突了。
这是通过组件名的唯一性来保证选择器的唯一性,从而保证样式不会污染到组件外。
BEM保证样式不冲突的核心就是:在元素名中加入唯一的标识。这个标识在BEM中对应的是模块名,也可能是一个独一无二的乱序字符串。
BEM的命名规矩:
block:块,Element:元素,Modifier:修饰符
通过给每个元素添加它的父级block模块作为前缀,使得目标的安全性变得更加简单了。BEM还有助于消除页面和body类对嵌套或者附加样式依赖。1
2
3.block {}
.block__element {}
.block--modifier {}
上面的例子展示了一个BEM项目的类结构,下划线()被用来区分元素,而用连字符(–)是用来修饰元素的。
. block 代表了更高级别的抽象或组件。
. blockelement 代表.block的后代,用于形成一个完整的.block的整体。
. block–modifier代表.block的不同状态或不同版本。1
2
3
4
5<div class="page-btn">
<button type="button" class="page-btn_prev">上一页</button>
<!-- ... -->
<button type="button" class="page-btn_next">下一页</button>
</div>
BEM禁止使用子代选择器。
子选择器的弊端:
- 造成命名冲突。
- 如果层次关系过长,逻辑不清晰,非常不利于维护。
- 子代选择器还会造成权重过大的问题,当我们要做响应式的时候,某个带样式的元素需要适配不同的屏幕,此时,我们还要不断的确认该元素之前的选择器写法!为了覆盖前面权重过大的样式,甚至通过添加额外的类名或标签名来增加权重。
BEM+Emmert1
2
3
4
5<form class="search-form">
<input type="text" class="search-form__username">
<input type="password" class="search-form__password">
<button id="J_Submit" class="search-form__submit--active"></button>
<form>
对于这段代码,当你使用了Emmet时候,可以省略掉block的字段,直接用一个连接符(-),然后在末尾加上标识符 |bem 来让Emmet按照BEM解析。1
form.search-form>input.-username+input.-password[type=password]+button.-submit--active|bem
然后按下“Tab”键,即可快速插入代码。
SUIT
Suit起源于BEM,但是它对组件名使用驼峰式和连字号把组件从他们的修饰和子孙后代中区分出来。1
2
3
4
5.u-utility {}
.ComponentName {}
.ComponentName--modifierName {}
.ComponentName-descendantName {}
.ComponentName.is-someState {}
通过消除潜在的混乱连字符号连接元素名来使得选择器的可读性更强。1
2
3.ProductDetails {}
.ProductDetails-price {}
.ProductDetails-title--sale {}
SMACSS
SMACSS使用一套五个层次来划分CSS给项目带来更结构化的方法。1
2
3
4
5Base - HTML elements & defaults
Layout -Page structure
Module - Re-usable code bloks
State - Active/Inactive etc
Theme - Typography and colour schemes etc
这个增加的组织和结构提高了输出的CSS的效率。这个方法同样适用于需要添加或者删除层次的地方。
参考资源:
- 为什么我们需要BEM http://blog.lxjwlt.com/front-end/2015/10/08/why-bem.html
- BEM的定义:http://www.w3cplus.com/css/bem-definitions.html
- BEM思想之彻底弄清BEM语法: http://www.w3cplus.com/css/mindbemding-getting-your-head-round-bem-syntax.html
- BEM进化史:http://www.w3cplus.com/css/the-history-of-the-bem-methodology.html
- 如何看待CSS中BEM的命名方式:http://www.zhihu.com/question/21935157
- 值得参考的css理论:OOCSS、SMACSS与BEM: https://segmentfault.com/a/1190000000704006
- CSS哲学伪命题:https://segmentfault.com/a/1190000004494678
- 精简高效的css命名准则方法:
http://www.zhangxinxu.com/wordpress/2010/09/%E7%B2%BE%E7%AE%80%E9%AB%98%E6%95%88%E7%9A%84css%E5%91%BD%E5%90%8D%E5%87%86%E5%88%99%E6%96%B9%E6%B3%95/