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

:has() 的浏览器支持
请注意,我们在这里提到的 :has()
伪类并没有同样级别的支持,因此请谨慎使用:has()
:

下次你的代码中有冗余选择器时,不要忘记使用方便的:is()
伪类。
网友评论