最近,关于 :is()
伪类选择器 的讨论非常热烈,这可能是因为 Safari 14 已经支持它,现在所有主要浏览器都支持它。Miriam 在推特上谈论它,Kevin Powell 制作了一个视频,Šime 将其加入了 Web 平台新闻,Robin 也 提到了它。Bramus 用这“三个重要的事实”强调了它
1.
:is()
的选择器列表具有容错性
2.:is()
的权重与其最具体的参数相同
3.:is()
不适用于伪元素选择器 (目前)
此外,当然,它的主要功能是使原本冗长、复杂且容易出错的选择器更容易编写。权重方面尤其有趣。Miriam 指出了一些可以使用它的技巧,比如在不实际选择任何元素的情况下提高权重。
假设你想使用 .button
类进行选择,但希望它拥有极高的权重
:is(.button, #increase#specificity) {
/* specificity is now (0, 1, 0, 0) instead of (0, 0, 1, 0)
}
我过去做过一些类似的愚蠢操作
.button.button.button {
/* forcing the selector to be (0, 0, 3, 0) instead of (0, 0, 1, 0) */
/* doesn't actually require element to have three button classes lol */
}
:is()
的技巧对我来说似乎更易于理解。
但是,如果你想以相反的方式处理权重并将其降低呢?好吧,这就是 :where()
伪类选择器的全部意义所在。从功能上讲,它与 :is()
完全相同。你提供一个用逗号分隔的选择器列表作为选择器链的一部分,它就会执行选择,并且具有相同的容错性。不同的是,整个 :where()
部分的权重为零 (0)。
Kevin 在视频中展示了 :is()
的一个有趣的陷阱
.card :is(.title, p) {
color: red;
}
.card p {
color: yellow;
}
你可能会认为 yellow
会胜出,但由于顶部 :is()
选择器中存在 .title
,因此该选择器的权重 (0, 0, 2, 0) 会胜过下面的 (0, 0, 1, 1)。
在这里,我们可以考虑使用 :where()
!如果我们改为使用 :where()
伪类选择器
.card :where(.title, p) {
color: red;
}
.card p {
color: yellow;
}
那么 yellow 就会获胜,因为顶部选择器的权重降低到 (0, 0, 1, 0),低于底部选择器的 (0, 0, 1, 1)。
应该使用哪一个?你知道,我不确定这里是否有非常可靠且经过时间考验的建议。至少我们都拥有这两种选择,这意味着如果你遇到麻烦,你都有工具可以使用。时间告诉我,保持权重较低 通常是一个更健康的选择。这为你提供了覆盖的空间,而如果你权重过高,你的选择就会减少。但是 :where()
的零权重非常极端,我可以看到这也会导致令人困惑的时刻。所以我的直觉告诉我,你可能应该先从 :is()
开始,除非你注意到需要混合使用权重更高的选择器;如果确实需要,则退回到 :where()
。
CSS 最缺乏的是 PREG 或 PCRE 模式。想象一下一个 div 标签,它拥有一个我不知道的类,例如:div.source-code,其中包含一些源代码,然后
……或者类似的东西……只有 ::word-match() 中的那些会被着色。我们以后将不再需要任何 js 高亮显示器。这将极大地提高整体性能。这将是 CSS 发生的最棒的事情。并且某些东西告诉我,它将在不久的将来出现。
客观上是错误的,几乎没有 js 高亮显示器像“将 x 单词着色为这种颜色”一样简单,否则你会遇到各种问题,例如无法突出显示插值字符串和嵌套注释是最明显的。更不用说,由于 js 高亮显示器已经使用正则表达式,因此性能将没有任何提升,并且会使 CSS 的实现难度提高 100 倍……
@某人
问题是 CSS 可以编写文本和字符。在屏幕上。不能绘制它们。真的吗?为什么。可能是因为大多数优秀的开发者都在修复和更新他们的 node.js 设置。查询选择器已经存在,能够解析第一个/最后一个字符和空格等。它不需要像 pcre 那样复杂,也不需要像你想象的那样难以实现。只需看看转换和简单的透明度。我仍然记得清楚,仅仅为了普通的淡入淡出效果,需要多少堆 js 代码@CPU,并且在最顶层看起来很漂亮。现在,一行 CSS 代码就能模拟这些堆栈了。
“
更不用说,由于 js 高亮显示器已经使用正则表达式,因此性能将没有任何提升,并且会使 CSS 的实现难度提高 100 倍……
”我知道 js 高亮显示器是如何工作的。我知道如何编写和修改词法分析器,这是我的爱好。问题是,js 应该做其他事情。js 越少,用户体验越好。:)
哇!这太棒了!我知道
:is()
,但不知道:where()
。至于在什么情况下使用哪一个,在表单样式方面,
:where()
有一个很好的用例。考虑一下输入元素的默认样式不幸的是,这已经与类具有相同的权重。如果你的基于类的输入样式以某种方式出现在样式表中(想想 Sass 中的
%foo
选择器),那么你的样式就会丢失这是一个非常好的场景,可以将
:where()
引入其中,然后并且你甚至有足够的权重空间来加入元素名称以确保万无一失。
你见过我 2.5 年前关于更简单、更直接的任意权重调整技术的博文吗?我认为它比使用
:is()
伪类更优雅。https://erraticdev.blogspot.com/2018/11/css-class-selector-with-id-specificity.html