CSS样式优先级先比选择器权重,权重相同时才看引入顺序;行内样式>内部/外部样式>@import;权重按(a,b,c,d)四元组逐位比较,非算术和;!important仅豁免单条声明,不改变权重。

引入顺序只在优先级相同时起作用
CSS 的最终样式不是“谁写在后面就赢”,而是先比选择器权重,权重一样才看谁后定义。比如 #header .nav a 和 .menu-link 同时作用于一个链接,前者权重是 (0,1,1,1),后者是 (0,0,1,0),前者直接胜出——此时哪怕 .menu-link 写在外部 CSS 文件末尾,也完全无效。
- 引入顺序(
顺序、位置、行内style属性)只影响「同权重规则」的胜负 - 外部 CSS 文件按
出现顺序加载,但浏览器会等全部 CSS 解析完再渲染,所以“加载快慢”不等于“生效先后” - 不要靠把样式塞到最后来“强行覆盖”,先检查选择器是否真的一样——常有人误以为
.btn和button.btn权重相同,其实后者多一个标签选择器,权重更高
四种引入方式的天然优先级梯队
引入方式本身自带一层硬性排序:行内样式 > 内部 / 外部 (二者平级)> @import。注意:@import 不仅优先级最低,还会阻塞并延迟 CSS 解析,2026 年已基本被弃用。
-
style="color: red":权重固定为 1000,能压倒任何 ID 选择器(100)或类组合(如.a.b.c= 30) - 内部
和外部.css文件权重相同,谁在 HTML 中更靠后(如第二个或在底部),谁覆盖前面同权重规则 -
@import必须写在开头,且实际解析顺序晚于所有,相当于“插队失败还迟到”
权重计算不是加法,而是“进位制比较”
很多人把权重当算术和,比如认为 #id .cls div(100+10+1=111)输给 .a.b.c.d.e(5×10=50),这是错的。真实比较是四元组 (a,b,c,d) 从左到右逐位比:
#nav ul li.active → (0,1,1,2) .nav-list li:hover → (0,0,2,2) /* b位:1 > 0 → 前者胜,哪怕后者c位更高 */
-
a:是否有属性(1 或 0) -
b:ID 选择器个数(#a #b= 2) -
c:类/属性/伪类个数(.a[href][data-id]:hover= 4) -
d:标签/伪元素个数(div::before span= 3) - 一旦某一位分出高低,后续位直接忽略——不存在“100+10 比 99+11 大”的情况
!important 是例外,但不是解药
!important 不改变选择器权重,而是给单个声明加“豁免权”:它跳过常规优先级和源顺序规则,只和别的 !important 比权重+顺序。滥用会导致调试雪崩——你改了 10 行 CSS,发现全被某个深埋的 !important 拦截了。
立即学习“前端免费学习笔记(深入)”;
- 两个
!important规则冲突?仍按权重 → 同权重再看谁后出现 -
!important无法穿透内联样式:行内style="color:red !important"仍是最高优先级 - 现代项目中,用 CSS 自定义属性(
--primary-color)或 scoped 样式(Vue/Svelte)替代!important更可控
真正难缠的不是规则本身,而是开发者常把「引入位置」和「选择器强度」混为一谈。比如把修复样式的补丁全堆在最后一个 里,结果遇到一个权重更高的外部组件样式,补丁直接失效——这时该做的不是再往后加 ,而是用浏览器开发者工具点开那个元素,看 computed styles 里哪条规则在生效,逆向定位它的选择器权重,再针对性提升你的规则。










