简化冗余选择器
如果你有像这样的冗余的 CSS
选择器:
1 | /* 😕 */ |
你知道你可以像这样重写它吗?
1 | /* 🤩 */ |
没错,:is()
伪类现在已经内置到普通的 CSS 中了。
你可以使用 :is()
来组合选择器的任何部分,例如,你可以类似地转换这个:
1 | .section h2, |
为仅仅这样:
1 | :is(.section, .aside, .nav) h2 { |
但 :is()
不仅对于父元素和子元素有用,它也可以选择多个相邻的选择器,比如:
1 | button:is(:focus, :hover, :active) { |
其行为等同于:
1 | button:focus, button:hover, button:active { |
与 :where()
的比较
:where()
是一个非常类似的伪类,与 :is()
值得一提。它们看起来非常相似:
1 | :where(.section, .aside, .nav) h2 { |
但区别在于 :where
的特异性为0,而 :is()
总是具有列表中最具体选择器的特异性。
那么,在这个 CSS 中,你知道按钮将会是什么颜色吗?
1 | :is(html) button { |
在上面的例子中,尽管以 :where()
开头的块位于以 :is()
开头的块下方,但 :is()
块具有更高的特异性(对于 html 标签,+1 对于按钮),而下方的块具有较低的特异性(对于 html 是0,因为它在 :where
中,+1 对于按钮)。
与 :has()
的比较
一个相关但非常不同的伪类是 :has()
。:has()
允许你选择包含匹配选择器(或一组选择器)的父元素。
:has()
的一个示例用例是不要给包含图像或视频的链接添加下划线:
1 | a { text-decoration: underline } |
现在,如果我们的 a 标签默认有下划线的文本,但我们的其中一个里面有图像或视频,对于任何匹配的锚点元素,下划线都将被移除。
你也可以将其与 :is()
结合使用:
1 | :is(a, button):has(img, video) { |
请注意,虽然 :has()
还不是所有主要浏览器都支持,因此请谨慎使用。
我们还需要预处理器吗?
现在你可能正在读这篇文章,并说“SCSS可以做到这一点!,你甚至可能更喜欢它的语法:
1 | .active { |
你说得对,这确实非常优雅。但似乎每一天 CSS
在原生环境中都获得了我们曾经需要 SCSS
(或其他预处理器)的功能。
CSS
变量也是CSS
自身的另一个不可思议的添加,这就引出了一个问题,你到底何时或多久需要预处理器:
1 | /* 纯粹的现代 CSS*/ |
这并不是说预处理器不再有用和有价值。
但我认为在某个时候,它们确实是处理任何非常用 CSS
(至少是优雅地处理)的必备工具,而现在情况已经不那么明显了。
最后一个惊喜…
CSS Working Group
正在积极努力将嵌套选择器直接添加到 CSS 中。他们正在积极地在三种可能的语法之间做出决定(称为选项“3”,“4”和“5”):
1 | /* 选项 3 */ |
你最喜欢哪一个?你的选择是否与官方调查中的获胜者相匹配?
剧透 : #3
赢得了调查,所以我们可能会很快得到一个非常类似于 SCSS
的嵌套语法,这是CSSWG
选择了调查获胜者的情况下的锦上添花。
选项 4 简直是一个绝对的灾难,需要在火焰中燃烧。
浏览器支持
:is() 和 :where() 的浏览器支持
:is() 和 :where() 伪类在所有主要浏览器中都得到支持:
:has() 的浏览器支持
请注意,我们在这里提到的 :has()
伪类并没有同样级别的支持,因此请谨慎使用 :has()
:
下次你的代码中有冗余选择器时,不要忘记使用方便的:is()
伪类。