抛弃 `!important` ,更优雅的提高CSS优先级

hello大家好,我是Range。

今天带来的这篇文章,讲的是一个CSS小技巧。我们都知道CSS的优先级规则,但是我还是第一次知道,通过简单的重复一遍同一个class,也能提高优先级,相当于对应权重位置+1 ,以后覆盖三方组件的样式,可以考虑抛弃 !important 和 额外的父元素class了。

下面是正文部分。



在Web前端开发中,CSS的优先级(Specificity)是一个非常重要的概念。它决定了当多个CSS规则应用于同一个元素时,哪条规则会最终生效。如果你曾经遇到过样式不按预期生效的情况,那很可能是因为优先级的问题。

理想与现实的差距

在理想的世界里,我们的CSS代码应该是井井有条且易于维护的。然而,现实往往并非如此。当然,你的CSS代码可能是完美的,但其他人的CSS代码可能会与你的代码产生冲突,或者应用了一些你不想要的样式。

更糟糕的是,你可能无法编辑那些其他的CSS代码。也许它来自你正在使用的UI库,或者是某个第三方小部件或嵌入内容,甚至可能是另一个团队或部门的代码。

此外,你可能也无法完全控制HTML标记。无法通过添加额外的classid属性来帮助你覆盖需要调整样式的DOM元素。

不知不觉中,你就被卷入了CSS优先级的战斗中。你的选择器需要比他们的优先级更高。一些经验不足的开发者可能会选择使用!important,但你知道这并不可取。是的,你的样式需要胜过他们的,但你应该以优雅的方式实现。

下面介绍一个奇怪但有效的小技巧,帮助你在不写太多“hacky”代码的情况下解决这些问题。

示例场景

假设你正在开发一个网站,其中有一个新闻订阅表单。表单中有一个复选框,但它的位置有点偏移。你需要修复这个问题,但这个表单是一个嵌入页面的第三方小部件,你无法直接修改它引入的CSS。

你检查了复选框,发现它的top位置需要调整。当前的位置是由选择器.newsletter .newsletter__checkbox .checkbox__icon设置的,其优先级为(0,3,0)

你可能会尝试使用相同的选择器来应用你想要的top值:

/* 覆盖新闻订阅复选框的top位置 */
.newsletter .newsletter__checkbox .checkbox__icon {
  top5px;
}

如果CSS的加载顺序是可预测的,并且你能确保你的CSS规则在他们的规则之后加载,那么这种方法就足够了。如果多个CSS选择器针对同一个DOM元素且具有相同的优先级,那么最后加载的规则将“胜出”。

然而,假设你无法保证CSS的加载顺序,那么你就需要提高你选择器的优先级。你可以通过在DOM中查找一些额外的类名来增加选择器的复杂性:

/* 更多的类!优先级现在是(0,4,0) */
.parent-thing .newsletter .newsletter__checkbox .checkbox__icon {
  top5px;
}

或者,你可以利用该元素是一个<span>的事实,添加一个元素选择器:

/* 使用span元素选择器!优先级现在是(0,3,1) */
.newsletter .newsletter__checkbox span.checkbox__icon {
  top5px;
}

但这些方法可能会使你的代码变得脆弱。如果.parent-thing并非在所有页面都存在,或者.checkbox__icon被应用到了不同的元素上,你的高优先级选择器就会失效。

一个奇怪的小技巧

当浏览器计算CSS选择器的优先级时,它们实际上是在计算你组合了多少个ID、类、元素或等效选择器。有趣的是,你可以重复使用相同的选择器,每次重复都会增加优先级。CSS选择器第4级规范(https://www.w3.org/TR/selectors-4/#specificity-rules)中提到:

允许重复使用相同的简单选择器,并且每次重复都会增加优先级。

因此,你可以简单地重复(或多次重复)相同的选择器:

/* 重复.checkbox__icon,优先级现在是(0,4,0) */
.newsletter .newsletter__checkbox .checkbox__icon.checkbox__icon {
  top5px;
}

(注意,.checkbox__icon.checkbox__icon中间没有空格!因为它是一个复合选择器(https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors/Selector_structure#compound_selector),你正在针对一个单一的元素,该元素具有这个类。)

所以,这就是这个技巧。现在你可以通过重复选择器来提升优先级

在HTML中重复类名无效

需要注意的是,这个技巧只适用于CSS!在HTML中重复相同的类名不会影响任何针对该元素的CSS选择器的优先级。

<div class="badger badger badger">
  Mushroom!
</div>
<style>
  /* 优先级仍然是(0,1,0) */
  .badger {
    /* ... */
  }
</style>

这个技巧是否有点“hacky”?

这个CSS技巧是否有点“hacky”?也许吧。但我认为它有以下优点:

  • 避免使用!important,这很好。
  • 保持与你试图覆盖的原始选择器接近,代码的意图更清晰。
  • 可以轻松找到代码中对其他人CSS的覆盖,这在以后不再需要时可以方便地删除。

只要不过度使用,我认为这是一个在优先级困境中完全可以使用的合法技巧。


总结

CSS优先级是Web前端开发中一个非常重要的概念。通过理解优先级的计算规则,并掌握一些提高优先级的小技巧,你可以更好地控制样式的应用,避免样式冲突的问题。希望这个奇怪的小技巧能帮助你在开发中更加得心应手!


原文链接:https://cirrus.twiddles.com/blog/2024/08/21/double-your-specificity-with-this-one-weird-trick/


最后

还没有使用过我们刷题网站(https://fe.ecool.fun/)或者刷题小程序的同学,如果近期准备或者正在找工作,千万不要错过,题库主打题全和更新快哦~。


有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。

图片