<p>直接用 * { margin: 0; padding: 0 } 会放大隐式 Bug,因其暴力清零破坏语义元素原生样式(如 fieldset 边框、textarea 内边距、details/summary 交互),且权重低易被后续规则覆盖;normalize.css 需配合三处手动声明(box-sizing: border-box、img { max-width: 100% }、表单控件 font: inherit)并置于 <head> 最顶部加载才有效。</p>

为什么直接用 * { margin: 0; padding: 0 } 会放大隐式 Bug
它不修复问题,只掩盖表层现象:比如 fieldset 被强制归零后失去语义分组边框,textarea 原生内边距消失导致文字紧贴边缘,details/summary 的折叠交互样式被清空——这些都不是“多了一点 margin”,而是浏览器对语义元素的隐式行为被暴力截断。更麻烦的是,* 权重低,后续哪怕写一句 button { margin: 8px },就立刻失效,调试时你根本看不出哪条规则赢了。
normalize.css 是修复而非重置,但它必须配合三处手动声明
它本身不设 box-sizing、不约束 img 宽度、也不统一表单控件字体继承,这三处漏掉,布局照样崩:
-
* { box-sizing: border-box }—— 必须加在 normalize.css 后立即声明,否则width: 100%+padding会撑破容器 -
img { max-width: 100%; height: auto }—— 否则响应式中图片溢出父容器,且不保持宽高比 -
button, input, select, textarea { font: inherit }—— 否则 iOS Safari 下表单控件字体异常小,Android Chrome 中 placeholder 文字错位
引入顺序错误会让 normalize.css 彻底失效
normalize.css 只有在 CSSOM 构建最早阶段生效才管用。常见失效场景:
- 把它放在
<link>链中第二个或更靠后的位置 —— 前面的 CSS 文件里若已定义h1 { margin: 24px },那 normalize.css 的h1 { margin: 0.67em }就被覆盖 - 通过
@import嵌在其他 CSS 文件里 —— 构建工具可能打乱加载时序,DevTools 的 Styles 面板里能看到规则被划掉 - 用 JS 动态插入(如
import('./normalize.css'))—— CSSOM 已构建完成,补救无效
正确做法:在 <head> 最顶部放唯一一条 <link rel="stylesheet" href="/css/normalize.css">,之后再引入你自己的 CSS。
立即学习“前端免费学习笔记(深入)”;
表单控件的“默认样式”其实是可访问性保障,别一并清掉
很多团队在 reset 后给所有 input 加 outline: none,结果键盘用户 tab 到输入框时完全看不到焦点位置。normalize.css 保留了 :focus 的 outline 行为,但如果你覆盖了它,必须提供等效替代:
- 用
outline: 2px solid #007bff替代原生灰色虚线,确保对比度达标 - 对
button和a[role="button"]显式设置outline-offset: 2px,避免焦点框被圆角裁切 - 不要仅靠
box-shadow模拟 focus 状态——屏幕阅读器无法感知,且部分 Windows 高对比模式下会失效
真正难处理的不是 margin 或 padding,而是那些看不见的交互契约:focus 样式、表单验证提示、details 的展开状态、select 的下拉箭头渲染逻辑——它们不写在你的 CSS 里,却由浏览器默认样式悄悄承载。


















