跳转至

工程实践与踩坑 — 命名、组织与最常见的六个错

原书拆成第 22 章(最佳实践)和第 23 章(常见错误),合并讲——两章是一枚硬币的两面: 第 22 章说「怎么不埋雷」,第 23 章说「炸了怎么排」。合起来是这本书的工程观收束: CSS 好写难维护,项目一大,拼的就是纪律。

1. 这一章在全书链条里的位置

到这里,全书所有「部件」都讲完了;这一章讲「装配与保养」。 它也是前 22 章纪律的总回收站——BEM 回应第 02 章的「最简单选择器」、 reset 回应第 04 章的 border-box、特异性陷阱回应第 03 章的计分表。

2. 顶层全景:四条军规,六个大坑

四条军规(第 22 章):            六个大坑(第 23 章):
① 命名:BEM,类名即文档           ① 外边距折叠 → flex + gap
② 数值:全部进 :root 变量        ② 特异性陷阱 → 别用 ID,别 !important 救场
③ 嵌套:不超过三层               ③ 固定宽度   → max-width: 100%
④ 起手:reset 起手式             ④ height:100% 没反应 → 改 100vh
                                ⑤ z-index 失灵 → 先给 position
排障总纲:CSS 不报错,             ⑥ 漏写单位 / 漏分号 → 检查元素看划掉的规则
用 DevTools 看「谁赢了你」

图说:左表是预防,右表是抢救;底下那行是唯一的排障工具。

3. 核心原理:四条军规(原书第 22 章)

军规一:命名用 BEM

BEM(Block Element Modifier,块-元素-修饰符)是一套类名语法: 块__元素--修饰符,双下划线隔层级,双连字符隔状态1:

.card { }                 /* 块:独立的卡片组件 */
.card__title { }          /* 元素:卡片里的标题 */
.card--dark { }           /* 修饰符:深色版本的卡片 */
<div class="card card--dark">
  <h2 class="card__title">Professional CSS</h2>
</div>

为什么值得全军推广:类名本身就是结构文档(看名字就知道谁属于谁), 而且天然低特异性——全是一个类(0,0,1,0),谁也不压谁,第 03 章的战争从源头上打不起来。 书里把它定义为「让类名自文档化、防特异性问题」的流行命名约定2。

军规二:数值全部变量化

:root {
  --primary: #007bff;
  --spacing-unit: 1rem;
  --border-radius: 8px;
}
.button {
  background-color: var(--primary);
  padding: var(--spacing-unit);
  border-radius: var(--border-radius);
}

颜色、间距、圆角——所有「会被复用的数」定义在 :root 一次(第 12 章变量), 引用处只见名字。换主题、改品牌色,动的是定义处几个值3。 配套的辅助类(utility)是该思路的轻量版:.text-center、.mt-20、.hidden 这类 单一职责小类,让组件保持干净4。

军规三:嵌套别超三层

/* 坏:五层,特异性 0,0,5,0,日后没法覆盖 */
.nav .menu .item .link .icon { color: red; }
/* 好:扁平的 BEM 类 */
.nav__icon { color: red; }

深层嵌套产生高特异性,日后的任何修改都要打赢它——或者上 !important, 战争由此开始。书里定的线:最多三层5。

军规四:起手 reset

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img { max-width: 100%; display: block; }

box-sizing 全量(第 04 章)、清默认边距(第 13 章的 ul、h1 自带间距)、 图片两行(第 12 章)。每个项目的第 0 行 CSS6。 配套的句子级纪律:简写只在「设三个边以上」时用,margin: 0 0 10px 0 不如直接 margin-bottom: 10px7;别写 left: 347px 这种魔法数,用百分比、flex、calc 让布局自己算8。

4. 核心原理:六个大坑,各配解法(原书第 23 章)

先立排障总纲:CSS 是沉默的

CSS 和 JavaScript 不同:写错了不报错、不崩溃,浏览器静默跳过那行, 或者默默用一个默认值9。所以「样式没生效」从来看不见错误提示—— 唯一的排障工具是浏览器的「检查元素」(Inspect Element):打开它, 能看到元素身上每条规则的胜负,被覆盖的规则会显示为划掉10。 「Inspect, don't guess」是这一章的题眼11。

坑一:外边距折叠(第 04 章复习)

期望 40px、实得 20px。解:别跟折叠搏斗,父级改 display: flex; flex-direction: column; gap: 20px;——flex 子项不折叠12。

坑二:特异性陷阱

#header     { color: red; }
.blue-text  { color: blue; }   /* 无效:打不过 ID */

解:给新选择器加具体性(header.blue-text),更根本的解是从源头不用 ID13。 书里把它叫「层叠陷阱」(Cascade Trap):新样式加进去没反应,因为被老的强选择器挡着14。

坑三:固定宽度撑破手机

width: 600px 在 375px 的手机上就是横向滚动的元凶。解: width: 100%; max-width: 600px;——能缩能放,上限照旧15。

坑四:height: 100% 没反应

百分比高度要求父元素先有明确高度,父级没设就是没反应。解:要一屏高直接用 height: 100vh(第 12 章视口单位,不依赖父级)16。

坑五:z-index 设了 9999 还被人压着

z-index 只对非 static 元素生效(第 05 章)。解:先补 position: relative17; 若还不行,就是撞上了层叠上下文(第 05 章边界),去找是谁给祖先设了 opacity/transform/filter。

坑六:单位与分号

非零必带单位(margin: 10 无效,margin: 10px 才行;0 本身除外)18; 漏分号坏的是下一条声明19。配套的大小写坑:HTML 类名区分大小写, CSS 写 .Main-Nav 配 HTML 的 class="main-nav" 就是 styled 了个寂寞20。

5. 作者的判断与证据

  • 「频繁用 !important = 该重构了」——诊断断言:症状到药方一步到位21。
  • 「DRY(不重复)、KISS(保持简单)」——两条总原则挂在章首22。
  • 「嵌套三层上限」——经验阈值,本书未给推导。
  • 「Inspect, don't guess」——方法论断言,配了具体操作(看划掉的规则)11。
  • 证据类型同全书;本章的断言因为全是工程经验,「无数据」不构成缺陷——这类知识本就以经验形式传承。

6. 边界与局限

  • BEM 一节没提它的竞争者(如 utility-first 的 Tailwind、CSS Modules 的局部作用域)—— 对「该选哪套方法论」这个真问题,本书只有 BEM 一个答案。
  • reset 一节是「手写 reset」;现代 Normalize.css、preflight 的差异与选型未提。
  • 性能部分(只动 transform/opacity)重复了第 11 章,未量化(没有「重排一次多少毫秒」的量级感)。
  • 没讲团队协作(代码评审、样式删除策略——「没人敢删的死代码」只在章首抱怨了一句)。

判断(我们的,不是书里的): 「四条军规 + 六个坑 + 一个工具」是全书最该打印贴墙的两页。 它对「编程语言与系统研究」也有一处独特价值:BEM + 低特异性 + 变量集中, 是「无作用域语言上的模块化工事」的完整案例——CSS 没有 import 没有局部变量, 纪律全是约定俗成,这套约定是前端四十年踩坑史的结晶。 如果错,会错在: 随着 CSS 原生嵌套、@layer、作用域样式(@scope)普及, BEM 与「三层上限」的必要性都在下降——本书没给这条演进线, 读者会把 2015 年代的工事当成永久真理。

7. 可带走的

  1. BEM:块__元素--修饰符,类名即文档、特异性天然平1。
  2. 颜色间距字号进 :root 变量;单一职责小类做辅助34。
  3. 嵌套 ≤ 3 层;简写只在 ≥3 边时用;魔法数用百分比/calc 替代578。
  4. 起手 reset 四行,每个项目第 0 行6。
  5. 排障第一工具是检查元素,看被划掉的规则——别猜11。
  6. 六坑速查:折叠→gap;特异→别用 ID;定宽→max-width;100%→100vh;z-index→先 relative;单位→非零必带1215161718。
  7. !important 成瘾 = 重构信号21。

8. 原文地图

主题 原书章 原文位置
DRY/KISS Chapter 22: CSS Best Practices text/23-ch01-1-chapter-overview.txt:19(搜「DRY」);:21 搜「KISS」
BEM 语法与示例 同上 text/23-ch01-1-chapter-overview.txt:29(搜「BEM」);:33 搜「block__element--modifier」
变量集中管理 同上 text/23-ch01-1-chapter-overview.txt:54(搜「Theming」);:60 搜「:root」
嵌套三层上限 同上 text/23-ch01-1-chapter-overview.txt:80(搜「3 levels」)
辅助类 同上 text/23-ch01-1-chapter-overview.txt:94(搜「Utility-First」)
标准 reset 同上 text/23-ch01-1-chapter-overview.txt:102(搜「Standard Reset」)
!important 成瘾 同上 text/23-ch01-1-chapter-overview.txt:118(搜「Addiction」)
魔法数 同上 text/23-ch01-1-chapter-overview.txt:124(搜「Magic Numbers」)
沉默的错误 Chapter 23: Common CSS Mistakes text/24-ch01-1-chapter-overview.txt:21(搜「Silent Error」)
外边距折叠的修法 同上 text/24-ch01-1-chapter-overview.txt:29(搜「Margin Collapsing」)
层叠陷阱 同上 text/24-ch01-1-chapter-overview.txt:50(搜「Cascade Trap」)
固定宽度修法 同上 text/24-ch01-1-chapter-overview.txt:67(搜「Fixed Widths」)
height: 100% 的坑 同上 text/24-ch01-1-chapter-overview.txt:86(搜「Invisible」)
z-index 失灵 同上 text/24-ch01-1-chapter-overview.txt:99(搜「Z-Index」)
漏分号坏下一条 同上 text/24-ch01-1-chapter-overview.txt:113(搜「Missing Semicolons」)
非零必带单位 同上 text/24-ch01-1-chapter-overview.txt:115(搜「units」)
大小写坑 同上 text/24-ch01-1-chapter-overview.txt:117(搜「Main-Nav」)
Inspect 题眼 同上 text/24-ch01-1-chapter-overview.txt:125(搜「Inspect」)

  1. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:29,搜「BEM」;:33 搜「block__element--modifier」)。原文:「A popular naming convention that makes CSS classes self-documenting and prevents specificity issues. Syntax: block__element--modifier.」 ↩↩

  2. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:37,搜「Block:」)。原文三个部件:Block(独立组件,如 .card)、Element(块的一部分,如 .card__title)、Modifier(版本或状态,如 .card--featured)。 ↩

  3. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:54,搜「Theming」;:60 搜「:root」)。原文:「Define all core colors, spacing, and font sizes in the :root.」 ↩↩

  4. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:94,搜「Utility-First」)。原文:「Create small, single-purpose classes for common tasks to keep your main components clean.」,示例 .text-center、.mt-20、.hidden、.flex-center。 ↩↩

  5. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:80,搜「3 levels」)。原文:「Rule: Avoid nesting more than 3 levels deep. Reason: Deep nesting creates highly specific selectors that are nearly impossible to override without !important.」 ↩↩

  6. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:102,搜「Standard Reset」)。原文:「Start every project with a minimal reset to ensure a consistent baseline across all browsers.」,示例即 box-sizing/margin/padding + img 两行。 ↩↩

  7. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:122,搜「Redundant Shorthand」)。原文:「Using margin: 0 0 10px 0; is less readable than margin-bottom: 10px;. Only use shorthand when setting 3 or more sides.」 ↩↩

  8. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:124,搜「Magic Numbers」)。原文:「Avoid values like left: 347px;. Use percentages, flexbox, or calc() to make the layout more robust.」 ↩↩

  9. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:21,搜「Silent Error」)。原文:「Unlike JavaScript, CSS doesn't 'crash' if there is a mistake; the browser simply ignores the invalid line or applies a default, making bugs harder to spot.」 ↩

  10. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:125,搜「crossed out」)。原文:「Use the browser's 'Inspect Element' tool to see which styles are being overridden (crossed out).」 ↩

  11. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:125,搜「Inspect」)。原文:「Inspect, don't guess.」 ↩↩↩

  12. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:29,搜「Margin Collapsing」)。原文:「The Reality: The browser 'collapses' them into a single 20px space. The Fix: Use padding on the parent container or change the layout to flex or grid, which prevents collapsing.」 ↩↩

  13. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:50,搜「Cascade Trap」)。原文:「The Fix: Increase the specificity of the new selector or, better yet, remove the ID selector entirely in favor of classes.」 ↩

  14. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:61,搜「IGNORED」)。原文注释:「This class will be IGNORED because it is 'weaker' than an ID.」 ↩

  15. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:67,搜「Fixed Widths」)。原文:「The Mistake: Using width: 600px; on a container. The Fix: Use max-width: 100%; so the element can shrink on small screens.」配套写法见第 77–82 段:width: 100%; max-width: 1000px;。 ↩↩

  16. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:86,搜「Invisible」)。原文:「Percentages require the parent to have a defined height.」「Use Viewport Height (vh) or ensure the parent is explicitly sized.」 ↩↩

  17. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:99,搜「Z-Index」)。原文:「The Problem: z-index only works on elements with a position value other than static. The Fix: Add position: relative; (or absolute/fixed).」 ↩↩

  18. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:115,搜「units」)。原文:「You don't need 0px; 0 is fine. But you must have units on any number larger than zero (e.g., margin: 10 is invalid).」 ↩↩

  19. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:113,搜「Missing Semicolons」)。原文:「A missing ; at the end of a line will break the next property, not the current one.」 ↩

  20. 出处:「Chapter 23: Common CSS Mistakes」(text/24-ch01-1-chapter-overview.txt:117,搜「Main-Nav」)。原文:「HTML class names are case-sensitive. .Main-Nav in CSS will not style class="main-nav" in HTML.」 ↩

  21. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:118,搜「Addiction」)。原文:「If you find yourself using !important frequently, your selectors are likely too specific. Refactor your classes instead.」 ↩↩

  22. 出处:「Chapter 22: CSS Best Practices」(text/23-ch01-1-chapter-overview.txt:19,搜「DRY」;:21 搜「KISS」)。原文:DRY = Don't Repeat Yourself;KISS = Keep It Simple, Stupid。 ↩