ToolPal
CSS code on a computer screen

彻底搞懂CSS优先级:为什么我的样式没有生效?

📷 Negative Space / Pexels

彻底搞懂CSS优先级:为什么我的样式没有生效?

CSS优先级是前端开发必须掌握的核心概念。本文详解(A,B,C)计算规则、常见误区,以及如何用优先级计算工具快速排查样式冲突。

2026年4月13日1分钟阅读

每个前端开发者都遭遇过这种挫败感:明明是正确的CSS规则,在浏览器里就是不生效。打开DevTools一看,自己写的规则被划了删除线,被另一条不知道从哪来的规则覆盖了。

于是第一反应是加上!important

问题是,这只是把炸弹埋得更深。半年后,代码库里到处都是!important,没人敢动,一改就出问题。

CSS优先级的规则其实并不复杂,只是需要一次认真的梳理。掌握了它,你就能真正理解样式冲突的根源,而不是靠!important强行压制。

(A, B, C) 三列计算法

CSS优先级不是一个单一数字,而是由三列数字组成的值(A, B, C),比较时从左到右逐列进行。

A列:ID选择器 #header#main等ID选择器计入A列,每个贡献(1, 0, 0)。这一列的存在,是现代CSS实践中不推荐用ID选择器写样式的根本原因——一旦用了,覆盖起来非常麻烦。

B列:类选择器、属性选择器、伪类 类选择器(.nav)、属性选择器([type="text"])、伪类(:hover:focus:nth-child()),每个为B列加1。

C列:元素选择器、伪元素 divpul等元素类型选择器,以及::before::after等伪元素计入C列。

不计入优先级的内容 通配符选择器*、子代选择器>等组合器、以及:where()不影响优先级。

示例对比

/* (0, 0, 1) */
p { color: red; }

/* (0, 1, 0) */
.intro { color: blue; }

/* (0, 1, 1) */
.intro p { color: green; }

/* (1, 0, 0) */
#main { color: orange; }

/* (1, 1, 1) */
#main .content p { color: purple; }

若以上规则同时作用于同一元素,(1, 1, 1)最高,最后一条规则生效。

常见误解

误解一:选择器越长越具体,优先级越高

长度不等于优先级。.nav .list .item a.link看起来很精确,但优先级只有(0, 3, 2),遇到#header(1, 0, 0)直接输。

误解二:后写的样式一定覆盖前面的

只有当优先级完全相同时,写在后面的才胜出。如果优先级不同,不管顺序如何,高优先级的总是赢。

:is()、:not()、:where()的特殊处理

:not()会继承参数的优先级。:not(.hidden)因为.hidden的存在,优先级是(0, 1, 0)

:is()取参数列表中优先级最高的那一个。:is(#main, .nav, p)因为#main,整体优先级是(1, 0, 0),即使实际匹配的是.nav元素。这个行为让很多开发者感到意外。

:where()永远是0。在设计基础样式库时,把选择器放进:where()是一种让使用者能轻松覆盖的好习惯。

实战场景:覆盖第三方组件库样式

这是实际项目中最常见的优先级冲突场景:

/* 组件库的CSS */
.ui-btn.ui-btn--primary {
  background-color: #0066cc;
}

/* 自定义覆盖 */
.my-button {
  background-color: #ff5500;
}

组件库:(0, 2, 0),自定义规则:(0, 1, 0),自定义样式输了。

解决方式:

  1. 重复类名.my-button.my-button,优先级变成(0, 2, 0),打平
  2. 加父级上下文.app-wrapper .my-button,同样是(0, 2, 0)
  3. !important:真正万不得已时再用

使用CSS优先级计算工具

CSS优先级计算工具可以让你粘贴选择器后立即看到(A, B, C)的详细分解,不用在脑子里手动计算。

适合使用的场景:

  • 调试样式冲突时,把两条竞争规则放进去对比,立刻知道谁该赢
  • 写复杂选择器时先检查一下,确保优先级符合预期
  • 学习阶段:边改选择器边看数字变化,是理解优先级最直观的方式

工具的局限性

对常规选择器计算准确。复杂嵌套的:is()表达式以及Shadow DOM相关选择器(::slotted()::part())在边界情况下可能不够精确。精度要求高时,以浏览器开发工具为准。

写出低优先级CSS的最佳实践

样式不要用ID选择器 ID保留给JavaScript钩子和页面锚点,CSS中统一用类选择器,保持优先级可控。

选择器尽量短 .btn-primary.page .sidebar .nav .btn-primary更好,优先级更低,也更不容易因标签结构变化而失效。

采用BEM或类似命名规范 .card__title--featured这种写法让每个元素都能用单一类名精准定位,保持(0, 1, 0)的统一优先级层次。

!important只留给工具类 .hidden.visually-hidden这类必须始终生效的工具类是!important的正确用途。其他情况用!important往往意味着设计问题。

相关工具


CSS优先级是一个一旦真正理解就会受益长久的基础知识。它让你和浏览器站在同一边,而不是不断对抗它。使用CSS优先级计算工具来辅助调试,同时把规则内化到日常写CSS的习惯中,你会发现样式冲突越来越少,代码越来越清晰。

常见问题

分享文章

XLinkedIn

相关文章