今天我们来回顾几种常见的 CSS 的类名范式
CSS 的特性不断增强,预编译框架也层出不穷,但是即使使用 cssModules 这样的 scope 技术,我们仍需要一些范式来指导我们在局部更规范合理地给类取名字。
上面介绍的范式都不是什么新鲜事物,有的甚至相当有历史了,回顾他们主要目的在于帮助我们抬起头来重新想一想当初为什么我们选择了某一种范式(比如 BEM)来进行我们的类命名:
不同的范式的侧重不同,有些范式可以相互兼容组合,有些不能。他们大都是为了达成以下目标诞生的:
而同时它们也大都就以下几点达成了共识:
div.header
或 h1.title
.sidebar .title
下面我们就来逐一回顾这些 CSS 范式,在文末我们还会附赠两个控制选择器权重的小技巧:
Object-oriented CSS,即「面向对象的 CSS」
OOCSS 提倡对类进行必要的分离,以提高复用性,减少 CSS 代码量。这种范式主张将样式类按照以下两个纬度进行拆分:
这样的分离方式在较早的前端工程中时常能见到,有时会为不同的分层建立单独的样式表,如 layout.css, theme.css 等 随着前端工程组件化的普及,这种分离逐渐少见。但对于大型的组件库项目,仍能带来不少的好处。
block element modifier,即「区块 元素 状态」
BEM 制定了一套统一的类名命名规则:{区块名}__{元素名}--{状态名}
,例如一个卡片的类命名:
专门建立的学习Q-q-u-n ⑦⑧④-⑦⑧③-零①② 分享学习方法和需要注意的小细节,不停更新最新的教程和学习技巧(从零基础开始到WEB前端项目实战教程,学习工具,全栈开发学习路线以及规划)
卡片标题
内容
BEM 加强了 HTML 的语义化,令代码更易读易维护。 由于命名规则与组件化的工程架构契合度较高,使得它成为目前比较流行的类命名方式。 通过与组件命名保持同步,例如给页面组件加上 v-
的前缀,给 UI 组件加上 c-
的前缀,可以一定程度上规避类名冲突的问题(当然如果配合使用 scope 技术就更完美了):
另一方面我们也要看到 BEM 的劣势:
Scalable and Modular Architecture for CSS,即「CSS 的可扩展模块化架构」
这也是一种对样式进行拆分的范式。它有两个核心目标:
与其他范式不同的是 SMACSS 并不很强调不能使用 id 和层级选择器作为选择器,认为只要合适就行。与 OOCSS 类似,SMACSS 将类按职能分为以下 5 种:
对上述的类别,往往需要遵循特定的命名方式,例如下面这样:
l-
或 layout-
前缀is-
前缀,如 .is-active
,.is-hidden
SMACSS 的分层方式其实在日常业务中常常会有所借鉴,一个典型的例子就是一般项目都会用一个 reset.css 来「归一化」不同平台的样式以及设置一些全局通用的样式,这就是 Base 层。
Atomic CSS,即「原子 CSS」
提倡样式属性粒度的复用,如 .di { display: inline }
.fl { float: left }
这样。 早期的 CSS UI 库如 Bootstrap 时常能见到这样的类名:.lg .col-2 .btn
等等。 现在,在具备 CSS 预处理器的工程中,Atomic 的思路可以用作样式基础层,组合到更大的类中去。
比如与 BEM 结合,嵌套使用:
.people-card__link {
.fl;
}
借助预编译工具,我们可以从最小粒度的样式开始,一层一层组织更大粒度的样式层次。 例如下面的 ACSS 风格的 less 文件目录,从「夸克」到「原子」到「分子」,组建了一个工程的样式基础,实现了极大程度的复用:
专门建立的学习Q-q-u-n ⑦⑧④-⑦⑧③-零①② 分享学习方法和需要注意的小细节,不停更新最新的教程和学习技巧(从零基础开始到WEB前端项目实战教程,学习工具,全栈开发学习路线以及规划)
atomic-structuring/
├── atoms
│ ├── _button.less
│ ├── _flag.less
│ ├── _grids.less
│ └── _media.less
├── molecules
│ ├── _banner.less
│ ├── _custom-post.less
│ ├── _footer-nav.less
│ └── _heading-group.less
├── quarks
│ ├── _links.less
│ ├── _lists.less
│ ├── _paragraphs.less
│ └── _tables.less
└── utilities
├── _base-spacing.less
├── _clearfix.less
└── _reset.less
以上就是 CSS 类名范式相关的内容。也许你会发现,其实跟 JS 编程范式一样,你项目中的 CSS 架构往往也是几种范式的有机组合,而非完全执着于某一种理念。
有时我们不得不使用 id 来作为选择器,有时我们不得不加重选择器的权重来覆盖第三方库的样式。下面是针对这两个问题的有用的小技巧。
[id='{targetId}']
替代 #{targetId}
以获得与 .{className}
相同优先级的选择器.{className}.{className}