内联样式优先级最高(1000),其次ID选择器(100)、类名/属性/伪类(10)、元素选择器(1);特异性决定覆盖关系,!important仅单声明生效且破坏可维护性。
内联样式(style 属性)优先级最高,其次是 ID 选择器(#header),再是类名/属性/伪类(.btn、[type="submit"]、:hover),最后是元素选择器(div、p)。这个顺序不是凭感觉,而是由「特异性(specificity)」数值决定的,计算规则是:内联样式 = 1000,每个 ID = 100,每个类/属性/伪类 = 10,每个元素/伪元素 = 1。
常见误区是以为写在后面的样式一定生效——其实只要前面某条规则特异性更高,哪怕它在 CSS 文件靠前,也会覆盖后面低特异性的声明。
!important 会绕过特异性计算,但只对单个声明生效,且会破坏可维护性,不建议用于常规覆盖devtools 的「Computed」面板可直接看到每条样式的特异性值和是否被覆盖像 color、font-family、line-height 这类属性默认继承,但继承只发生在「未显式设置值」时。一旦子元素自身有任意来源(内联、CSS 规则、浏览器默认)设定了该属性,继承就中断了。
例如:body { color: #333; } 能让 p 继承颜色;但如果某个 p 上写了 color: inherit; 或 color: initial;,行为就不同了:
body { color: #333; }
p.special { color: initial; } /* 重置为浏览器默认色(通常是黑色),不是继承 body 的 #333 */inherit 强制继承父级计算值,哪怕父级本身也是继承来的unset 对继承属性等价于 inherit,对非继承属性等价于 initial
all: unset 会清空所有继承行为,慎用直接加 !important 是最省事但最危险的做法——它会让后续任何调整都必须用更强力的 !important,形成恶性循环。更可持续的方式是提升你自己的选择器特异性,或利用作用域隔离。
.btn 改成 .my-app .btn 或 body.my-theme .btn
CSS 放在第三方 CSS 之后加载(确保层叠顺序)(Vue)限制样式作用域,避免全局污染!important,仅限极少数无法通过结构控制的场景(如覆盖 inline style 的第三方组件)visibility 是继承属性,display 不是。这意味着:parent { visibility: hidden; } 会让所有后代不可见(即使子元素设 visibility: visible,也无效,除非父级是 collapse 表格相关);而 parent { display: none; } 会直接移除整个盒模型,后代根本不会渲染,自然谈不上继承。
这个区别直接影响调试逻辑——如果一个元素“消失了”,先检查它是被 display: none 移除了,还是被 visibility: hidden 隐藏了但占位还在。
display: none 触发重排(reflow),visibility: hidden 只触发重绘(repaint)visibility: hidden 的子元素可通过 visibility: visible 单独显示(仅当父级不是 hidden)display: none 完全忽略内容,visibility: hidden 仍可能读出实际覆盖样式时,最容易被忽略的是「父级 display 状态导致子元素根本没机会应用样式」,以及「以为设置了 color 就一定生效,却忘了祖先用了 visibility: hidden 把整块内容压住了」。