C02 可维护 CSS 与命名分层

2026-10-31 17:090 阅读约 12 分钟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 验证与讨论

  1. 打开 architecture/index.html,确认各层的样式按顺序生效(工具类可覆盖组件)。
  2. 注释掉 1-reset.css,观察页面间距整体变化,说明层顺序的作用。
  3. 新增一个 .card 组件,确认只需在 4-components.css 中追加。
  4. 用开发者工具搜索某个颜色值,确认只出现在变量文件中。
  5. 把 .card 整块复制到另一个页面,确认样式完整且未影响该页面原有元素。
检查项 预期结果 说明
层顺序 后引入的层优先级更高 @layer 或文件顺序
单向依赖 组件文件不引用布局类名 图 3-1
颜色唯一 颜色只出现在基础层 变量集中
新增成本 新组件只改一个文件 分层效果
可移植 组件复制到其它页面样式完整 表 3-3

讨论与局限。 五层结构在单页站点中显得过重,页面少于五个时两三层即可。另工具类与组件类混用会重新引入权重问题,需约定工具类只覆盖间距与显隐。

5 常见问题

现象 原因 处理
新组件影响旧组件 选择器命中了通用标签或后代 收敛为单一类选择器
样式改动风险高 缺少分层,规则互相覆盖 按五层重构
类名无法复用 命名绑定页面语义 用块级通用名,语义放修饰符
删除规则后页面异常 存在跨层隐式依赖 补齐显式样式
权重战争 层层嵌套选择器 单类 + @layer 解决

6 结论

序号 结论 依据
1 命名是 CSS 唯一的作用域手段 表 3-1
2 五层单向依赖,禁止反向引用 图 3-1
3 组件只用单类选择器 表 3-1
4 颜色与间距只出现在基础层 表 3-2

参考文献

[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

0/2000

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