reset.css 和 modern-normalize.css 必须作为 head 中第一个 link 标签加载,使用根相对路径或 cdn,禁止 @import 或 js 动态插入,否则重置失效导致样式异常。

reset.css 必须排在所有自定义 CSS 之前
浏览器按 <link> 在 中的顺序构建 CSSOM,reset.css 的作用是“归零”浏览器默认样式(如 h1 的 margin、button 的 padding),它必须在任何业务样式生效前就位。一旦 base.css 或 components.css 先加载并声明了 * { box-sizing: border-box } 或 body { margin: 0 },后续 reset.css 的同权重规则就会被跳过——不是没加载,是被层叠逻辑丢弃了。
- 正确顺序示例:
<link rel="stylesheet" href="/css/reset.css">→<link rel="stylesheet" href="/css/base.css">→<link rel="stylesheet" href="/css/components.css"> - 路径必须用根相对路径(
/css/reset.css),避免子页面中因相对路径计算错误导致 404;Network 面板里看 status 是 200 才算真正加载成功 - 别用
@import在base.css里引入 reset —— 它会把 reset 的解析拖到base.css全部下载完之后,实际顺序变成 base → reset,完全违背设计意图
为什么 modern-normalize.css 也得放最前
modern-normalize.css 不是可选补充,它是现代重置方案的默认入口,和传统 reset.css 一样承担“标准化默认行为”的职责:比如统一 input 的 focus 样式、修正 flex 在 Safari 中的默认值。它的加载时机要求相同——必须是 中第一个 <link rel="stylesheet">,否则 button:focus 等交互样式会在首帧渲染时漏掉,用户点击后才突然出现轮廓线。
- CDN 引入写法:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/modern-normalize@latest/modern-normalize.css"> - 如果同时用了 Tailwind 或 Bootstrap 这类框架 CSS,
modern-normalize.css仍需在它们之前——框架内部不自带完整 normalize,依赖外部重置打底 - 检查方式:打开 DevTools → Elements → 选中一个
input→ Styles 面板里找outline声明,来源文件名链接应指向modern-normalize.css,而不是被划掉后来自某个组件文件
动态插入或构建工具可能悄悄破坏顺序
Vite、Webpack 或 Vue/React SSR 模式下,即使你在 index.html 里手动写了正确的 <link> 顺序,构建产物中也可能被插件重排。例如 Vite 的 css.preprocessorOptions 或 Webpack 的 MiniCssExtractPlugin 会把 CSS 提取为独立 chunk,并按依赖图而非 HTML 书写顺序注入 。
- 验证方法:查看最终生成的 HTML 源码(右键 → View Page Source),确认
reset.css确实是第一个<link rel="stylesheet"> - Vite 用户可在
vite.config.ts中显式控制:build.rollupOptions.output.manualChunks将重置类 CSS 单独切块并确保前置 - 禁止用 JS 动态创建
<link>插入 reset —— 它总在 DOM ready 后执行,必然晚于静态标签,FOUC 已发生
顺序错一次,reset.css 就等于没加。它不报错、不警告,只在你改了 h2 字体却看到默认字号时,默默让你花半小时翻查 DevTools 的 Computed 面板。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











