后写颜色仍不变,根本原因是特异性碾压顺序;浏览器先按(a,b,c,d)计算权重,权重高者胜出,仅当权重相同时才由引入顺序裁决。

为什么
不是顺序问题,是特异性碾压了顺序。浏览器先算权重,再看位置。比如外部 CSS 里写了 #app .header(权重 110),而你内部 <style></style> 里只写了 .header(权重 10),哪怕 <style></style> 在 <link> 后面,也赢不了。
- 用开发者工具选中元素,点「Computed」→「Styles」,看哪条规则被划掉、为什么被划掉
- 右键某条规则 →「Reveal in Elements Panel」可跳转到对应 HTML 或 CSS 行号
- 别只盯着
里谁在前谁在后,重点查specificity值(浏览器会显示类似0,1,1,0的格式)
动态插入的
参与,但插入时机影响实际生效顺序。DOM 中后 append 的 <style></style>,其同权重规则会覆盖前面所有 <style></style> 和 <link> 里的同选择器声明——前提是它已插入并解析完成。
- JS 动态创建
document.createElement('style')并appendChild()后,样式立即生效 - 若插入时页面已渲染完毕,新样式可能触发重绘,但不会回溯修改已计算好的样式
- 避免在
DOMContentLoaded之后才插入关键样式,否则可能闪屏或布局抖动 - Vue / Svelte 的
<style scoped></style>编译后就是多个动态插入的<style></style>,靠属性选择器隔离,本质仍是靠特异性+插入顺序控制
@import 在
因为 @import 是异步加载,且插入位置不可控。它不阻塞当前 <style></style> 解析,也不保证在其他样式之前或之后生效,极易打乱预期覆盖关系。
- 浏览器会把
@import当作一个独立请求发起,完成时间不确定 - 即使写在
<style></style>最开头,导入的 CSS 也可能晚于后续<link>加载完成 - 生产环境必须禁用,改用构建工具做依赖合并,或用
<link rel="stylesheet">显式声明 - 检查 Network 面板,能看到
@import请求往往排在其他 CSS 之后,甚至跨域失败也不报错
框架注入的样式和手写的
没有绝对优先,只看最终 HTML 中的物理顺序和选择器特异性。Vite、Next.js、Vue CLI 等构建工具会在 HTML 中重排 <link> 和 <style></style> 位置,你看到的源码 ≠ 实际加载顺序。
立即学习“前端免费学习笔记(深入)”;
- 打开浏览器「View Page Source」,确认
<link>和<style></style>的真实 DOM 顺序 - SSR 场景下,服务端吐出的
<style></style>可能早于客户端挂载的框架样式,但框架常会清空并重写 - React 的
useInsertionEffect或 Vue 的createApp(...).mount()后插入的样式,大概率晚于初始 HTML 中的<style></style> - 真正难调的,是多个框架插件各自往
插<style></style>,顺序由插件注册顺序决定,而非代码书写顺序
<style></style> 写在哪,而是多个来源(框架、插件、SSR、JS 动态注入)共同拼出的最终 结构——它几乎从不按你写的顺序来。



















