在开发中很容易使用!important去增大优先级,这是不好的方法,那有没有更优雅的方式来实现我们覆盖的诉求呢?
实例
假设你正在开发一个网站,该网站有一个新闻订阅表单。它包含一个复选框,但复选框的位置有点偏。你需要修正这个问题,但注册表单是一个嵌入到页面上的第三方组件,你无法直接修改它的 CSS。
你通过浏览器检查了复选框,确定只要改变它的 top 位置即可。当前的位置是通过选择器.newsletter .newsletter__checkbox .checkbox__icon
设置的,它的权重为(0,3,0)
一开始你可能会使用相同的选择器来修改 top 值:
/* 覆盖新闻通讯复选框的顶部位置 */
.newsletter .newsletter__checkbox .checkbox__icon {
top: 5px;
}
当 CSS 的顺序是固定的,并且你可以保证你的 CSS 规则一定在他们的后面的情况下,这足够了。因为『后来居上』:即如果有多个相同的 CSS 选择器选择了同一个DOM元素,那么最后出现的将“获胜”。
然而,大多数时候你无法保证代码顺序。此时你需要增加选择器的优先级。你可以在 DOM 中寻找一些额外的类名,一般从父元素中添加:
/* 更多的类名!权重现在是(0,4,0) */
.parent-thing .newsletter .newsletter__checkbox .checkbox__icon {
top: 5px;
}
或者你发现这个元素恰好是一个 ,可以将其加入选择器提高优先级:
/* 权重现在是 (0,3,1) */
.newsletter .newsletter__checkbox span.checkbox__icon {
top: 5px;
}
但所有这些方法都有副作用,都会使你的代码变得脆弱。如果 .parent-thing
突然不见了呢,比如你升级了某个外部依赖;或者如果 .checkbox__icon
从 span
改成了不同的元素怎么办?突然间,你的高优先级选择器什么也选不到了!
当浏览器计算 CSS 选择器优先级时,它们本质上是在计算你组合了多少 ID、类、元素或等效选择器。实际上可以多次重复同一个选择器,每次重复都会增加权重
CSS 选择器 Level 4 规范 写到:CSS 选择器允许多次出现相同的简单选择器,而且可以增加权重。因此,你可以通过重复(三次、四次……)相同的选择器提高权重:
/* 双重 .checkbox__icon!权重现在是 (0,4,0) */
.newsletter .newsletter__checkbox .checkbox__icon.checkbox__icon {
top: 5px;
}
PS: .checkbox__icon.checkbox__icon
中没有空格!它是一个选择器,因为你针对的是具有那个类的单个元素。
该技巧其实在 MDN !important 章节 有示例(重复了3次#myElement):
#myElement#myElement#myElement .myClass.myClass p:hover {
color: blue;
}
p {
color: red !important;
}
在 HTML 中重复无效
PS:这个技巧只在 CSS 中有效!在 HTML 中重复相同的类名对优先级没有任何影响。
<div class="badger badger badger">
Mushroom!
</div>
<style>
/* 权重仍然是 (0,1,0) 而非 (0,3,0)*/
.badger {
/* ... */
}
</style>