必须放在内,否则触发fouc(文字跳变、按钮错位、媒体查询失效)及ssr hydration失败;浏览器解析时遇该标签会立即阻塞dom构建并加载cssom,放中则导致重绘。

核心 CSS 的 <link> 必须放在 里,不是“建议”,而是避免 FOUC(无样式内容闪现)和渲染异常的刚性要求;放错位置会导致首屏文字跳变、按钮错位、媒体查询失效,甚至 SSR hydration 失败。
浏览器解析 HTML 时遇到 <link rel="stylesheet"> 会立即阻塞 DOM 构建
这是关键机制,不是可选行为。浏览器流式解析 HTML,一旦碰到 <link rel="stylesheet">,就会:
- 立即发起 CSS 请求
- 暂停后续 HTML 解析与 DOM 构建
- 等待该 CSS 下载、解析、生成 CSSOM 后才继续
这个阻塞只在 中有效——因为此时 DOM 还没开始渲染。如果 <link> 在 里,DOM 已经解析出大量节点并尝试渲染,再加载 CSS 就只能重绘,用户肉眼可见“先白后跳”。
<link> 放在 里不会报错,但会静默触发 FOUC
现代浏览器仍会下载 CSS 文件,但无法保证样式在首屏内容渲染前就绪。典型现象包括:
- 文字先用 font-family: sans-serif 崩出来,几百毫秒后才换成你设的 "Inter", system-ui
- display: flex 容器里的子元素先堆成一列,再突然排成一行
- @media (max-width: 768px) 根本不生效,因为媒体查询依赖 CSSOM 就绪,而它来晚了
- 移动端尤其明显:布局抖动、滚动卡顿、首屏按钮偏移
即使放对了位置,<link> 也可能不生效
常见静默失败原因:
- rel 属性缺失或拼错,比如写成 rel="style" 或 rel="css" —— 浏览器直接当普通链接处理,不阻塞也不解析
- href 路径错误,返回 404 或空响应,DevTools Network 面板里看状态码和响应体
- <link> 被包裹在 <script></script> 或 <meta> 里,不是 的直接子元素
- 使用了 @import:它在 <style></style> 块内是同步阻塞且无法并行下载,比 <link> 更慢,应删掉
真正影响首屏体验的不是位置,而是 CSS 加载时机
把 <link> 放进 只解决了“顺序问题”,没解决“延迟问题”。网络往返、TLS 握手、服务器响应都会让外部 CSS 至少延迟几百毫秒。所以:
- 首屏必需样式(如 header 高度、按钮背景色、基础字体声明)必须提取出来,用 <style></style> 内联在 最顶部
- 内联 CSS 体积控制在 ≤14 KB,否则拖慢 TTFB 和 TCP 初始拥塞窗口
- 非关键 CSS 用 <link rel="preload" as="style" onload="this.rel='stylesheet'"> 异步加载,注意 IE 不支持 onload,需 fallback
最常被忽略的一点:服务端渲染(SSR)框架如 Next.js 或 Nuxt,要求 <link> 在最终输出的 HTML 字符串中真实存在于 内——如果靠 JS 动态拼接 内容,hydration 时可能找不到对应样式上下文,导致首屏样式丢失或 layout shift。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











