注册
web

抛弃 `!important` 吧,一个更友好的技巧让你的 CSS 优先级变大

image.png



原文:Double your specificity with this one weird trick



在一个理想的世界里,我们的 CSS 代码组织得井井有条,易于维护。然而,现实往往大相径庭。你的 CSS 代码是完美的,但其他人那些烦人的 CSS 可能会与你的风格冲突,或者应用了你不需要的样式。


此外,你可能也无法修改那些 CSS。也许它来自你正在使用的 UI 库,也许是一些第三方的小组件。


更糟糕的是,HTML 也不受你控制,添加一些额外的 classid 属性来覆盖样式也并不可行。


不知不觉中,你被卷入了一场 CSS 优先级之战。你的选择器需要优先于他们的选择器。开发者很容易被『诱惑 😈』去使用 !important,但你知道这是不好的实践,我们能不能有一种更优雅的方式来实现我们覆盖的诉求?


本文将教给你一个技巧,可以用一种不是很 hacky 的方式应对这些情况 👩‍💻。


示例 🔮


假设你正在开发一个网站,该网站有一个新闻订阅表单。它包含一个复选框,但复选框的位置有点偏。你需要修正这个问题,但注册表单是一个嵌入到页面上的第三方组件,你无法直接修改它的 CSS。


通过浏览器检查复选框,确定只要改变它的 top 位置即可。当前的位置是通过选择器.newsletter .newsletter__checkbox .checkbox__icon 设置的,它的权重为 (0,3,0)


image.png


一开始你可能会使用相同的选择器来修改 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 突然不见了呢,比如你升级了某个外部依赖(比如 antd 😅)?或者如果 .checkbox__iconspan 改成了不同的元素怎么办?突然间,你的高优先级选择器什么也选不到了!


当浏览器计算 CSS 选择器优先级时,它们本质上是在计算你组合了多少 ID元素或等效选择器。实际上可以多次重复同一个选择器,每次重复都会增加权重CSS 选择器 Level 4 规范 写到:



CSS 选择器允许多次出现相同的简单选择器,而且可以增加权重。



因此,你可以通过重复(三次、四次……)相同的选择器提高权重:


/* 双重 .checkbox__icon!权重现在是 (0,4,0) */
.newsletter .newsletter__checkbox .checkbox__icon.checkbox__icon {
top: 5px;
}


注意 .checkbox__icon.checkbox__icon 中没有空格!它是一个选择器,因为你针对的是具有那个类的单个元素



现在你可以简单地重复几次选择器来提升优先级!



译者注:该技巧其实在 MDN !important 章节 有示例(以下示例重复了3次#myElement):


#myElement#myElement#myElement .myClass.myClass p:hover {
color: blue;
}

p {
color: red !important;
}


在 HTML 中重复 🚫


注意,这个技巧只在 CSS 中有效!在 HTML 中重复相同的类名对优先级没有任何影响。


<div class="badger badger badger">
Mushroom!
div>


总结 🎯



CSS 可以多次重复同一个选择器,每次重复都会增加权重 🏋️‍♂️



这种 CSS 技巧是否有点 hack?也许是。然而我认为它让我们:



  • 避免诉诸于 !important
  • 『就近原则』提高可读性:重复多次的选择器,这样代码的意图对读者来说更清晰
  • 这种模式让你很容易在代码中找到其他人的 CSS 覆盖,如果不再需要我们可以放心删除

只要你不过度使用它,我认为这是一个完全合法且 Robust 的技巧至少相比我们之前学会的所有技巧,下次处理棘手的覆盖三方样式情况时可以考虑用一用。


是否还有更好的解决办法?其实有,@layer 是官方推荐的最佳实践但是兼容性不好 Chrome>=99,而且使用场景有限。


作者:Legend80s
来源:juejin.cn/post/7411686792342618153

0 个评论

要回复文章请先登录注册