Menu

CSS !important:工作原理与使用场景

!important 让一条声明胜过所有普通声明,无论它们的优先级如何。本文准确讲解它能压过什么、什么能压过它、底层的优先级是如何计算的,以及解决样式冲突更干净的办法。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

!important 的作用

在值的后面加上 !important,这条声明就会胜过同一元素上同一属性的所有普通声明。选择器的优先级和源码顺序都不再起作用。

没有 !important 的话,ID 选择器会胜出,文字会是蓝色。在编辑器里删掉 !important 就能看到。

语法

selector {
  property: value !important;
}

它写在值的后面、分号的前面。它只作用于这一条声明,而不是整条规则。它也可以用在简写属性中(margin: 0 !important; 让四个方向都变成 important),以及 style 属性中。

谁胜过谁

对于页面作者编写的样式,从弱到强依次是:

等级声明示例
1样式表中的普通声明p { color: blue; }
2style 属性中的普通声明<p style="color: blue">
3样式表中的 !importantp { color: blue !important; }
4style 属性中的 !important<p style="color: blue !important">

在同一个等级内,先比优先级,再比声明出现的顺序:后出现的胜出。

这是 !important 在日常中唯一正当的用法:覆盖一个你无法修改的内联样式,比如第三方小组件写入的样式。

两条声明都是 !important 时

!important 对上 !important,就回到常规规则:优先级高的胜出,优先级相同时后写的声明胜出。

!important 就是这样不断升级的:一旦某条规则用了它,要覆盖这条规则的规则也必须用它,优先级又开始一路攀升。

一张表看懂 CSS 优先级

优先级就是选择器的权重。数三个数字:

列计入的内容示例选择器优先级
AID 选择器#nav(1,0,0)
B类、属性、伪类.btn、[type="text"]、:hover每个 (0,1,0)
C类型选择器、伪元素p、::before每个 (0,0,1)
无*、组合符(>、+、~、空格)*、ul > li不增加权重

先比较 A 列;只有相同时才看 B 列,然后是 C 列。所以 #nav a(1,0,1)胜过 .menu .item .link a(0,3,1):一个 ID 的分量超过任意数量的类。

理解了这张表,你就能避免使用 !important:大多数“我的 CSS 不生效”的问题,都是因为别处有一条优先级更高的规则,在开发者工具的 Styles 面板里可以看到你的声明被划掉了。

更干净的替代方案

  • 让优先级持平,再依靠顺序。 在库的样式表之后加载你自己的样式表,并使用一个至少同样具体的选择器。
  • 用 :where() 降低另一条规则的优先级。 :where() 里面的一切都算作零,所以用它编写的基础样式很容易被覆盖。
  • 用 CSS 变量作为入口。 一个读取 var(--btn-bg) 的组件不必和它的选择器较劲就能换主题。参见 CSS 变量。

用 JavaScript 设置 !important

element.style.color = 'red !important' 是行不通的:这个值无效,会被忽略。请使用带第三个参数的 setProperty:

el.style.setProperty('color', '#f59e0b', 'important');

常见错误

  • 写错了位置。 color: !important red; 是无效的;它要写在值的后面。
  • 在 @keyframes 里使用。 关键帧里标记了 !important 的声明会被忽略。
  • 每个冲突都用它来解决。 应该在开发者工具里找到胜出的那条规则,让你的优先级与它持平,或者降低它的优先级。
  • 以为它会影响另一个属性。 color: red !important 对 background 毫无作用。
  • 忘了内联的 !important 会胜过你的。 页面样式表中没有任何规则能覆盖 style="color: red !important";只能修改这个属性本身,比如用 JavaScript。

常见问题

CSS 中的 !important 有什么作用?

它让一条声明优先于同一元素上同一属性的所有普通声明,不管选择器的优先级或书写顺序如何。把它写在值的后面:color: red !important;。

怎么覆盖 !important?

用另一条 !important 声明,它的优先级更高,或者优先级相同但在样式表中位置更靠后。带 !important 的内联 style 胜过样式表中所有的 !important。

!important 能覆盖内联样式吗?

能。样式表中带 !important 的声明胜过 style 属性中的普通声明。但它无法胜过本身也标记了 !important 的内联声明。

使用 !important 是不好的做法吗?

如果用它来打赢优先级之争,是的:下一次覆盖也得用 !important,样式表就会变得难以修改。对于必须始终生效的工具类(比如 .hidden)、覆盖第三方的内联样式,以及用户样式表,使用它是合理的。

CSS 优先级是怎么计算的?

数三列:ID 选择器;类、属性和伪类;类型选择器和伪元素。从第一列开始逐列比较,所以 #nav a(1,0,1)胜过 .menu .item a(0,2,1)。通用选择器 * 和组合符不增加任何权重。

Coddy 编程语言插图

和 Coddy 一起学编程

开始