这篇也同时发布在我另一个独立博客
这篇文章主要谈谈Nicolas对css命名的看法。还总结了一些其他前端团队的css规范供大家参考。
可以说是一位大神级的人物。这篇文章是他它对css组织和命名的一些看法,也相当值得我们一读。
这篇文章主要是谈html的语义(semantics)化。比如他反对class的命名以内容为驱动(content-derived),比如这样
News
[news content]
因为容器的内容是news所以class就要是news?他认为class具有以下几个特征
- 其实以内容为驱动的语义化在html标签上已经体现出来了,比如说标题使用h标签,文章使用p标签
- class名主要的用处是为css和javascript服务,如果你既不需要添加样式又不需要再js中引用,那要id和class有什么用
- class名取的再怎么恰当,有意义,对机器来说是没有任何意义的
- class名应该在开发者之间传递有用的信息
另一种取class名的作法是,从网页的架构和功能上来区分。最具复用性的组件的名字往往是脱离内容的。
前端架构中,模板(template),组件(component),面向对象(object-oriented)的意义就在于,开发有限的可复用的模块来容纳不同的内容。所以以编程为驱动(而不是以内容为驱动)的class名称主要的目的也应该是,提供有意义的,灵活的,可复用的表现层/行为层的hooks(怎么翻译?)给开发者使用
一个灵活的,具有复用性的组件既不能对特定的dom树结构有依赖,也不能指定特定的元素类型来承载。它应该被所有容器所接纳,并且可以被任意的主题化。
应该避免使用css的类型选择器,比如下面这个例子
.btn { /* styles */} .uilist { /* styles */} .uilist a { /* styles */}
首先因为css优先级的规则关系,.btn会被.uilist a的样式覆盖;其次,uilist这个组件始终需要一个a标签嵌套在其中。
所以最好的作法应该是指定特定的class名称
.btn { /* styles */} .uilist { /* styles */} .uilist-item { /* styles */}
Component modifiers
没错,这里的modifier和bem中的modifier是一致的概念。
通常组件也会有一些变种,比如一个按钮我们需要不同的背景色和边框。主要有两种模式来创建这样的组件
- single-class
.btn,.btn-primary { /* button template styles */} .btn-primary { /* styles specific to save button */}
- multi-class
.btn { /* button template styles */} .btn-primary { /* styles specific to primary button */}
作者推荐的是第二种。考虑一种情况,比如当我需要统一调整btn组件时,第一种方法需要这么修改
/* "single-class" adjustment */ .thing .btn,.thing .btn-primary,.thing .btn-danger,.thing .btn-etc { /* adjustments */}
而第二种方法只需要这么修改
/* "multi-class" adjustment */.thing .btn { /* adjustments */}
之前的想法是想法是想把人人和淘宝的规则再分别整理一遍,后来发现,既然已经成规则,他们的文档已经很抽象很精辟,没有办法再再整理了,如果真的要整理的话只能直接复制粘贴了。所以还是都不在这里一一展示了。
它们的命名规则和之前的几篇文章是一致的,比如对每一个组件都单独命名,绝不使用元素或者类型选择器。除了本系列文章谈的一些原则可以得到映射。我们能从这些规范里学习到的更多是细节……太多太多细节了!按照这些细节来书写css,保证团队里每个人书写的css绝对都是一样的,也绝对都能互相看懂,可维护性太棒了!