:has vs :matches - 选择器级别 4

:has vs :matches - Selectors Level 4

只是想知道 CSS(选择器 4)伪选择器 :has:matches

之间有什么区别

规范 http://dev.w3.org/csswg/selectors-4/#overview 说:

E:matches(s1, s2)
an E element that matches compound selector s1 and/or compound selector s2
§4.2 The Matches-any Pseudo-class: :matches()

E:has(rs1, rs2)
an E element, if either of the relative selectors rs1 or rs2, when evaluated with E as the :scope elements, match an element
§4.4 The Relational Pseudo-class: :has()

简而言之:

  • E:has(rs1, rs2) 一个不同的元素 F 匹配与 E[=165 相关的任何选择器参数 时匹配 E =].如果你知道jQuery的:has() selector,这完全是一回事

  • E:matches(s1, s2)E 本身 匹配任何选择器参数时匹配 E。将 :matches() 视为 :not() 的直接对立面,如果 E 本身不匹配任何参数,则它匹配 E。1 您也可以认为 :matches() 作为 jQuery 的 .filter() method.

    的伪 class 版本

    这个表示法等同于将每个选择器参数与 E 连接起来(前提是您实际上可以连接它们),这样您就有了一个选择器列表 (E)(s1), (E)(s2)。例如,div:matches(.foo, .bar) 等同于 div.foo, div.bar.

选择器 div:matches(p)div:has(p):

最直接地证明了这种根本区别
  • div:has(p) 匹配 具有 一个 p 后代的任何 div 元素。 这与 div p 非常相似,除了前者针对 div 后者针对 p.

  • 因为 div 永远不会 成为 pdiv:matches(p) 永远不会匹配 任何事物。 (同样,div:not(p) 将匹配所有 div 元素。)


这是一个更复杂的示例,其中的选择器不那么荒谬:

div:has(.foo, .bar)
div:matches(.foo, .bar)

带有以下标记:

<div class="foo"></div> <!-- [1] -->
<div class="bar"></div> <!-- [1] -->

<div class="foo bar">   <!-- [2] -->
  <p></p>
</div>

<div>                   <!-- [3] -->
  <p class="foo"></p>
</div>

<div>                   <!-- [3] -->
  <div>                 <!-- [3] -->
    <p class="bar"></p>
  </div>
</div>

<div>                   <!-- [4] -->
  <div class="foo">     <!-- [5] -->
    <p class="bar"></p>
  </div>
</div>

哪些元素与哪些选择器匹配?

  1. 匹配 div:matches(.foo, .bar)
    第一个 div 元素具有 "foo" class,第二个 div 元素具有 "bar" class,因此每个元素都满足其各自的:matches()伪class.

  2. 中的选择器参数
  3. 匹配 div:matches(.foo, .bar)
    第三个 div 元素有 both classes,所以它匹配两个选择器参数。

    关于特异性的注释:这两个参数具有相同的特异性,使得总的特异性 (0, 1, 1),但是当一个元素匹配多个具有不同特异性值的选择器参数时,规范说 the specificity is that of the most specific argument that is matched .

  4. 匹配 div:has(.foo, .bar)
    每个 div 元素 都有一个 后代元素(在本例中为 p),其中 class 与其在:has()伪class.

  5. 匹配 div:has(.foo, .bar)
    这个 div 元素有一个 div.foo 后代和一个 p.bar 后代,因此它满足两个相对选择器参数。

    关于特异性的说明:因为:has()还没有在fast profile中,因此暂时排除在CSS之外,特异性的概念根本不适用。有计划在 CSS 中使用的快速配置文件中包含此的有限版本,但目前还没有具体的内容。有新进展会适时补充。

  6. 匹配 div:matches(.foo, .bar)div:has(.foo, .bar)
    这个 div 元素匹配两个伪 classes:

    • .foo(因为它有"foo"class),而
    • 后代 "bar" class.

    此元素也将匹配 div:matches(.foo, .bar):has(.foo, .bar),这将是一个有效的 4 级选择器,因为复合选择器可以具有伪classes.

    [=166 的任意组合=]

:matches():has() 之间的另一个区别是 :has() 接受所谓的 relative selector。相对选择器有一个 scope;选择器作用域本身就是一个完整的主题,但就 :has() 而言,作用域元素始终是您附加 :has() 伪 class 的元素。但是,更重要的是,相对选择器可以有一个隐含的后代组合器,或者显式地以组合器开始,例如 >+~——这个组合器是连接其余部分的东西其作用域元素的相对选择器。

例如,虽然:has()默认为祖先-后代关系,但您可以传递以+开头的相对选择器,然后它成为相邻的兄弟关系:ul:has(+ p) 匹配直接跟在 p 之后的任何 ul 元素(不一定是 包含 一个 p 后代的元素)。

至于 :matches(),虽然概述 table 说它接受复合选择器列表,但据我所知,它是否会采用复合选择器列表尚未确定或复杂的选择器,以及在哪个配置文件中(快速或完整)。但是复合选择器只是 Selectors 3 当前所称的新名称 sequence of simple selectors and a complex selector is an entire series of compound selectors and combinators. A relative selector is more like a complex selector in that respect. See this answer,用于选择器中使用的各种术语的非详尽列表。


1 是的,这是 "arguments" 的复数形式 — 在 Selectors 4 中,:not() can now accept a list of selectors 与单个简单选择器相对。一项急需的增强功能,但也是为了使其与其他新功能伪classes.

保持一致