CSS引入顺序仅在特异性、来源和重要性均相同时才起作用;改顺序无效主因是选择器特异性不足(如Bootstrap用#app .btn而自定义仅用.btn),!important不跨<link>边界,动态插入CSS更易导致顺序失控。

CSS文件引入顺序只在特异性、来源、重要性都相同时才起作用——它不是“谁后写谁赢”,而是“谁没资格参战,就根本轮不到比顺序”。
为什么改了顺序样式还是不生效
你把custom.css挪到bootstrap.css后面,但.btn颜色依然没变,大概率不是顺序错了,而是你的选择器特异性太低:
-
bootstrap.css里可能是#app .btn-primary:hover(特异性0,1,1,1) - 而你的
custom.css里只写了.btn-primary(特异性0,0,1,0) - 浏览器压根不会拿这两条规则去比“谁在后面”,因为前者权重高,直接胜出
打开 Chrome DevTools → Elements → 选中元素 → 右侧 Styles 面板,看被划掉的规则,悬停提示 “This rule was overridden by …” —— 点文件名跳转,再比对两者的 Specificity 四位数。
为什么!important加了也没用
!important 不跨 <link> 边界,它只在单个样式表内部提升声明层级:
立即学习“前端免费学习笔记(深入)”;
-
A.css:h1 { font-size: 24px !important; } -
B.css(后加载):h1 { font-size: 32px; } - 最终生效的是
32px,因为B.css来源靠后,且未使用!important,但它已无需比权重就能覆盖
想靠 !important 强制赢?得确保它出现在最终生效的那个文件里,且该文件本身加载顺序靠后;否则只是给失效规则多贴一张无效标签。
动态插入的 CSS 怎么让顺序失控
用 JS 创建 <link> 并 appendChild 到 <head>,默认插在末尾,看似“最强”,实则不可控:
- Vue SFC 的
<style scoped>编译后生成[data-v-xxx]属性选择器,权重等同类,但插入时机晚于 HTML 中静态<link>,可能意外覆盖全局.container - Vite 或 Webpack 项目中,
import './theme.css'的顺序决定打包后 CSS 内容顺序,和 HTML 里写的<link>无关 - 微前端场景下,子应用各自注入 CSS,
<link>顺序完全由加载时序决定,无法靠 HTML 排列解决
真正难的不是调顺序,而是当你看到某个按钮在首页突然变粗、变色、错位时,得立刻判断:是特异性输了?是 !important 被另一个文件无视了?还是 JS 插入的样式正踩着 DOM 尚未 ready 的时间点,在框架样式之前抢跑了?


















