C02 可维护 CSS 与命名分层
C02 可维护 CSS 与命名分层
摘要:样式表失控的信号有三个:改一个颜色要搜全项目、新增组件偶然影响旧组件、没人敢删任何规则。解法不是更严格的编码规范,而是分层:重置、基础、布局、组件、工具各占一层,层与层之间只有单向依赖。本文给出命名约定、文件切分与层结构的组合方式。
关键词:命名约定,BEM,分层,单向依赖,样式组织
所属:frontend/css / C-高级 | 上一篇:C01-现代布局与逻辑属性 | 下一篇:C03-渲染性能
1 引言
CSS 没有模块系统,所有规则共享一个全局作用域。命名是唯一的作用域手段,分层是唯一的依赖控制手段。
本文给出两者组合后的最小可用结构。范围见表 1-1。
| 项 | 本文覆盖 | 本文不覆盖 |
|---|---|---|
| 命名 | BEM 与元素前缀两种约定 | 原子化框架的类名体系 |
| 分层 | 重置、基础、布局、组件、工具五层 | 完整设计系统架构 |
| 文件 | 按层拆文件与引入顺序 | 构建与打包(C05) |
2 预备知识
| 项 | 要求 | 核对方式 |
|---|---|---|
| 环境 | 本地服务器可用 | 浏览器能打开 localhost |
| 文件 | css-practice/architecture/ 目录 |
含五个 CSS 文件 |
| 浏览器 | Chrome 130+ | 开发者工具可用 |
| 前置 | B01 | 理解层与权重 |
3 原理与实现
3.1 单向依赖的五层
层与层之间只允许上层引用下层,禁止反向,如图 3-1 所示。
flowchart TD
L1["1 重置<br/>消除默认差异"] --> L2["2 基础<br/>排版与变量"]
L2 --> L3["3 布局<br/>容器与栅格"]
L3 --> L4["4 组件<br/>卡片、按钮、导航"]
L4 --> L5["5 工具<br/>间距、可见性"]
L5 -.->|"禁止反向引用"| L4
图 3-1 五层的依赖方向
图上可见:组件不能写布局层的类名,布局层也不能针对具体组件写规则;双向引用是样式表失控的开端。
3.2 命名与文件结构
/* 运行环境:Chrome 130+;css-practice/architecture/components.css */
.card { background: var(--surface-alt); border-radius: var(--radius); }
.card__title { font-size: 1.125rem; margin-block-end: 0.25rem; }
.card__meta { color: var(--text-muted); font-size: 0.875rem; }
.card--featured { border: 1px solid var(--brand); }
.btn { padding: 0.5rem 1rem; border-radius: 0.5rem; }
.btn--primary { background: var(--brand); color: #fff; }
.btn--ghost { background: transparent; border: 1px solid currentColor; }
architecture/
├─ 1-reset.css
├─ 2-base.css
├─ 3-layout.css
├─ 4-components.css
└─ 5-utilities.css
命名与分层规则见表 3-1。
| 规则 | 写法 | 反例 |
|---|---|---|
| 块用名词 | .card |
.card-wrapper-box |
| 元素用双下划线 | .card__title |
.card .title |
| 修饰用双连字符 | .card--featured |
.card.featured-red |
状态用 is- |
.is-open |
.open-card-style |
| 工具类用单职责 | .mt-2、.visually-hidden |
.margin-top-small-blue |
| 不嵌套超过两层 | .card__title |
.page .main .card .title |
五层的常见内容见表 3-2。
| 层 | 内容 | 不允许出现 |
|---|---|---|
| 重置 | 盒模型、外边距归零、字体继承 | 颜色与组件样式 |
| 基础 | 变量、body、标题、链接、表单 |
具体组件 |
| 布局 | 容器宽度、栅格、页头页脚结构 | 组件内部细节 |
| 组件 | 卡片、按钮、导航、表格 | 页面级定位 |
| 工具 | 间距、隐藏、文本截断 | 组合多个属性的类 |
3.3 一个组件的完整落地
<!-- 运行环境:Chrome 130+;css-practice/architecture/index.html -->
<article class="card card--featured">
<h3 class="card__title">可维护 CSS</h3>
<p class="card__meta">发布于 2026-10-31 · 阅读 8 分钟</p>
<p class="card__body">块、元素、修饰三段命名让同一组件的不同变体各自独立。</p>
<button class="btn btn--primary" type="button">继续阅读</button>
</article>
/* 运行环境:Chrome 130+;css-practice/architecture/4-components.css */
.card {
--card-padding: 1.25rem;
padding: var(--card-padding);
border-radius: var(--radius);
background: var(--surface-alt);
}
.card--featured { border: 1px solid var(--brand); }
.card__title { font-size: 1.125rem; margin-block-end: 0.25rem; }
.card__meta { color: var(--text-muted); font-size: 0.875rem; }
.card__body { margin-block: 0.5rem 1rem; line-height: 1.7; }
BEM 三段拆解见表 3-3。
| 段 | 在本例中的类名 | 含义 | 约束 |
|---|---|---|---|
| 块 | .card、.btn |
独立可复用的组件 | 不依赖父级,可放在任意处 |
| 元素 | .card__title、.card__body |
块的组成部分 | 只在块内使用,不单独出现 |
| 修饰 | .card--featured、.btn--primary |
块或元素的变体 | 与块同时写,不单独生效 |
| 状态 | .is-open、.is-loading |
运行时的临时状态 | 由脚本增删,不写死在 HTML |
表 3-3 BEM 四段命名的职责划分
判断命名是否合格的唯一标准:把组件整块复制到另一个页面后,样式仍然完整且不影响原有页面。不满足则说明出现了跨层依赖或上下文选择器。
4 验证与讨论
- 打开
architecture/index.html,确认各层的样式按顺序生效(工具类可覆盖组件)。 - 注释掉
1-reset.css,观察页面间距整体变化,说明层顺序的作用。 - 新增一个
.card组件,确认只需在4-components.css中追加。 - 用开发者工具搜索某个颜色值,确认只出现在变量文件中。
- 把
.card整块复制到另一个页面,确认样式完整且未影响该页面原有元素。
| 检查项 | 预期结果 | 说明 |
|---|---|---|
| 层顺序 | 后引入的层优先级更高 | @layer 或文件顺序 |
| 单向依赖 | 组件文件不引用布局类名 | 图 3-1 |
| 颜色唯一 | 颜色只出现在基础层 | 变量集中 |
| 新增成本 | 新组件只改一个文件 | 分层效果 |
| 可移植 | 组件复制到其它页面样式完整 | 表 3-3 |
讨论与局限。 五层结构在单页站点中显得过重,页面少于五个时两三层即可。另工具类与组件类混用会重新引入权重问题,需约定工具类只覆盖间距与显隐。
5 常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| 新组件影响旧组件 | 选择器命中了通用标签或后代 | 收敛为单一类选择器 |
| 样式改动风险高 | 缺少分层,规则互相覆盖 | 按五层重构 |
| 类名无法复用 | 命名绑定页面语义 | 用块级通用名,语义放修饰符 |
| 删除规则后页面异常 | 存在跨层隐式依赖 | 补齐显式样式 |
| 权重战争 | 层层嵌套选择器 | 单类 + @layer 解决 |
6 结论
| 序号 | 结论 | 依据 |
|---|---|---|
| 1 | 命名是 CSS 唯一的作用域手段 | 表 3-1 |
| 2 | 五层单向依赖,禁止反向引用 | 图 3-1 |
| 3 | 组件只用单类选择器 | 表 3-1 |
| 4 | 颜色与间距只出现在基础层 | 表 3-2 |
- 上一篇:C01-现代布局与逻辑属性
- 下一篇:C03-渲染性能
- 返回:C00-总结 | 科目 README
参考文献
[1] MDN Web Docs · 组织 CSS,https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/Organizing(访问于 2026-10-31)
[2] BEM 方法论,https://getbem.com/naming/(访问于 2026-10-31)

评论 0
还没有评论,快来抢沙发吧~