Normalize.css必须放在所有CSS最前面加载,它是基线定义者而非兜底样式;需覆盖伪元素、SVG、iframe等易忽略节点,并用font:inherit修复表单继承断裂。

它不是“锦上添花”,而是防止你在第3天就为 button 垂直居中不对、h1 在 Safari 里突然变小、input 点击区域窄得离谱而反复切到 DevTools 查 computed 样式。
为什么不能等出问题再加 Reset/Normalize?
浏览器 UA 样式不是“可选功能”,而是渲染链起点。一旦你写了第一条自定义 CSS(比如 body { margin: 20px; }),就已经在不可逆地叠加在未标准化的基线上——后续所有调试都得先问自己:“这个 margin 是我写的,还是 Chrome 默认塞的,还是 Safari 暗中加的?”
- Chrome 给
body默认margin: 8px,Firefox 是8px,但 IE 旧版是10px;没重置前,你连“页面左右留白”都控制不住 -
sub和sup的vertical-align在各浏览器中值不同,不统一的话,化学式或数学公式直接错位 - 表单控件(
select、textarea)的font-size和line-height被重置后若没补font: inherit,文字会缩成一团,且无法通过父级 font-size 控制
Normalize.css 必须放在所有 CSS 最前面加载
它不是“兜底样式”,而是基线定义者。顺序错了,等于没加。
- 错误写法:
@import 'normalize.css';写在某个组件.vue的<style>里 → Webpack/Vite 可能把它打包进组件 chunk,SSR 时重复注入,优先级混乱 - 正确姿势:在
index.html的<head>顶部,第一个<link rel="stylesheet">就引入normalize.css - 用 CSS-in-JS(如 Emotion)时,必须显式设
prepend: true,否则它会被插入到动态生成的 style 标签之后,立刻被覆盖
Reset.css 的坑:表单控件失焦不是 bug,是你忘了修
像 Eric Meyer 的经典 reset 会把 button、input 的 font-size 强制设为 100%,但切断了继承链——如果父容器没设字体,它们就按 UA 默认字号(通常 13–16px 不等)渲染,且不随根字体变化。
立即学习“前端免费学习笔记(深入)”;
- 现象:
button文字比周围段落小一圈,input行高塌陷,光标贴着上边缘 - 修复不是加
font-size: 1rem,而是补这一行:button, input, select, textarea { font: inherit; line-height: normal; } - 别只信预览效果,打开 DevTools 的 Computed 面板,点开
button,看font-size是不是显示 “inherited from body” —— 如果是 “13.3333px”,说明继承断了
box-sizing: border-box 必须覆盖到伪元素和 SVG
老式 reset 用 * { box-sizing: border-box; } 看似简单,但漏掉 ::before、::after 和内联 <svg>,响应式栅格在 iOS 或 Android WebView 里依然会溢出。
- modern-css-reset 和 reseter.css 用
:where(:root) { box-sizing: border-box; }+*::before, *::after { box-sizing: border-box; }才真正兜住 - 内联
<svg>若含width属性,在部分旧 Android 浏览器中会无视max-width: 100%,得额外加display: block -
iframe完全不在任何主流 reset 覆盖范围内,需手动加iframe { width: 100%; min-height: 200px; }
真正容易被忽略的,是那些“看起来正常”的地方:比如 details 的箭头位置、mark 的背景色饱和度、audio 默认边框是否存在——这些细节在 Normalize.css v8.0+ 才被显式标准化,老项目若还在用 v7.x,prefers-reduced-motion 规则压根不会生效。


















