@supports 选择器()

Avatar of Chris Coyier
Chris Coyier

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

我之前没有意识到 @supports 对确定选择器支持的 支持如此广泛!我通常认为 @supports 是一种测试 property: value 对支持的方法。但使用 selector() 函数,我们也可以测试选择器支持。它看起来像这样

@supports selector(:nth-child(1 of .foo)) {

}

您只需将选择器直接放在括号之间,它就会进行测试。

上面的选择器实际上是一个很好的测试。它是一个“选择器列表参数”,适用于 :nth-child 和其类似选择器。在我写这篇文章时,它 仅在 Safari 中受支持

假设您希望浏览器支持此选择器。以下是一个示例。您知道对于 <ol><ul>,唯一有效的子元素是 <li>。但假设此列表还需要分隔符,所以您(我不是说这是一个好主意)做了这样的事情

<ul>
  <li class="list-item">List item</li>
  <li class="list-item">List item</li>
  <li class="separator"></li>
  /* ... */
</ul>

然后您还希望对列表进行斑马条纹。而且,如果您想要斑马条纹,则需要选择每个第二 .list-item,忽略 .separator。所以…

li:nth-child(odd of .list-item) {
  background: lightgoldenrodyellow;
}

但这只在 Safari 中受支持... 所以您可以这样做

@supports selector(:nth-child(1 of .foo)) {
  li:nth-child(odd of .list-item) {
    background: lightgoldenrodyellow;
  }
}

如果您不关心回退是什么,您甚至不需要使用 @supports。但是假设您确实关心回退。也许在支持的情况下,斑马条纹会完成您想要达到的 UX 的大部分工作,因此您只需要为分隔符留出一小块空间即可。但对于不支持的浏览器,您需要更强大的功能,因为您没有斑马条纹。

所以现在您可以同时设置两种情况的样式

@supports selector(:nth-child(1 of .foo)) {
  li {
    padding: 0.25em;
  }
  li:nth-child(odd of .list-item) {
    background: lightgoldenrodyellow;
  }
  li.separator {
    list-style: none;
    margin: 0.25em 0;
  }
}
@supports not selector(:nth-child(1 of .foo)) {
  li.separator {
    height: 1px;
    list-style: none;
    border-top: 1px dashed purple;
    margin: 0.25em 0;
  }
}

如果我们获得了 @when 语法,那么我们可以更简洁地编写它

/* Maybe? */
@when supports(selector(:nth-child(1 of .foo))) {

} @else {

}

总之,最终的结果是…

支持
不支持

还存在一个用于测试支持的 JavaScript API。我不确定这是否真的有效,但它似乎有效!在我写这篇文章时,它在 Chrome 中失败,但在 Safari 中通过

CSS.supports("selector(:nth-child(1 of .foo))")

当我编写这篇文章时,我在想… 嗯 - 哪些 CSS 选择器具有奇怪的跨浏览器支持?实际上并没有那么多。即使是那些确实具有奇怪的跨浏览器支持的,考虑一下您实际需要用 @supports 包装它们的用例数量(而不是让它失败),其实很少。

::marker 伪元素本来是一个很好的选择,但现在它已经被广泛支持了。我原以为不区分大小写的属性选择器,比如 [href$="pdf" i],会是一个不错的选择,但也不行,它也得到了很好的支持。:not(a, .b, [c]) 中的逗号分隔也是一样。也许像 :fullscreen / :-webkit-full-screen 这样的东西会很有趣且有用,因为它在 iOS Safari 中没有得到支持?