:has 是一个不宽容的选择器

Avatar of Geoff Graham
Geoff Graham

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 的免费积分!

在发布 CSS :has() 选择器 到老式年鉴的途中发生了一些小事。 我最初将 :has() 描述为一个“宽容”的选择器,其理念是它的参数中的任何内容都会被评估,即使其中一个或多个项目无效。

/* Example: Do not use! */
article:has(h2, ul, ::-scoobydoo) { }

看到里面的 ::scoobydoo 了吗? 这是完全无效的。 一个宽容的选择器列表会忽略那个无效的选择器,并继续评估剩余的项目,就好像它是这样编写的

article:has(h2, ul) { }

:has() 确实是一个宽容的选择器 在 2022 年 5 月 7 日发布的早期草案中。 但后来 在报告了一个问题后发生了改变,即宽容的特性与 jQuery 冲突,因为 :has() 包含一个复杂的 selector(例如 header h2 + p)。 W3C 决定 :has() 变成一个“不宽容”的选择器,这仅仅发生在几个星期前。

因此,我们之前的例子? 整个选择器列表无效,因为无效选择器无效。 但另外两个宽容选择器,:is():where(),保持不变。

有一个解决方法。 记住,:is():where() 是宽容的,即使 :has() 不是。 这意味着我们可以在 :has() 中嵌套这两个 selector 之一,以获得更宽容的行为

article:has(:where(h2, ul, ::-scoobydoo)) { }

您使用哪一个可能很重要,因为 :is() 的特异性由其列表中最特定的项目决定。 因此,如果您需要更不特定的东西,最好使用 :where(),因为它不会增加特异性分数。

/* Specificity: (0,0,1) */
article:has(:where(h2, ul, ::-scoobydoo)) { }

/* Specificity: (0,0,2) */
article:has(:is(h2, ul, ::-scoobydoo)) { }

我们更新了一些帖子以反映最新信息。 我看到很多其他需要更新的帖子,所以这只是对任何需要这样做的人的公告。