css :where()和:is()有什么区别?

iyzzxitl  于 4个月前  发布在  其他
关注(0)|答案(3)|浏览(81)

CSS最近添加了伪类:where():is(),我不明白什么时候使用哪一个。两者都可以用来选择多个元素。下面是一个片段,其中使用两个伪类实现了相同的功能:

span {
  display: inline-block;
  height: 100px;
  width: 100px;
  background-color: grey;
  margin-bottom: 10px;
}

:is(.span1-1, .span1-2):hover {
  background-color: firebrick;
}

:where(.span2-1, .span2-2):hover {
  background-color: teal;
}

个字符
有人能给予一个例子,他们的行为不同?

0md85ypi

0md85ypi1#

如前所述,区别在于特异性。这在MDN中提到过,尽管出于某种原因并不突出。另一方面,规范对它的描述要明确得多:

4.4.规格调整伪类::where()

Specificity-adjustment伪类:where()是一个函数式伪类,其语法和功能与:is()相同。与:is()不同的是,:where伪类及其任何参数都不会影响选择器的特异性-它的特异性始终为零。
有哪些使用情形?在您给出的示例中,它并不是非常有用。您不需要匹配或覆盖特定性的任何竞争选择器。您有一个基本的span规则,和一个自然覆盖它的:hover规则(即,仅通过特异性如何工作以及特异性最初设计的目的)。如果没有任何特殊或特殊的样式需要考虑,那么使用:is()还是:where()其实并不重要。
当你有一些更一般的规则,但这些规则有不必要的特定选择器时,:where()就很有用了,这些规则需要被一些更特殊的规则覆盖,而这些规则的选择器不那么特定。MDN和规范都包含了一个(非常)常见的用例示例--我不想简单地复述MDN上的内容,所以下面是规范中的一个:
下面是一个常见的例子,其中的特异性启发式不符合作者的期望:

a:not(:hover) {
  text-decoration: none;
}

nav a {
  /* Has no effect */
  text-decoration: underline;
}

字符串
然而,通过使用:where(),作者可以明确地声明他们的意图:

a:where(:not(:hover)) {
  text-decoration: none;
}

nav a {
  /* Works now! */
  text-decoration: underline;
}


与MDN不同的是,该规范并没有用英语真正解释这个用例,所以我会这样做。这里的“作者期望”是nav a CSS规则(我称之为专门化规则)将覆盖a:not(:hover)规则(我称之为通用规则)。表面上,这不会发生。
因为:hover伪类比类型选择器更具体,所以任何只有类型选择器的规则都不能覆盖a:not(:hover)的通用规则,而a:not(:hover)的通用规则适用于任何没有悬停的a。传统上,您需要 * 匹配 * a:not(:hover)的具体性,最简单的做法是复制有问题的位:

a:not(:hover) {
  text-decoration: none;
}

nav a, nav a:not(:hover) {
  /* Works, but not ideal, to say the least */
  text-decoration: underline;
}


或者,通过添加增加特异性而不影响匹配的选择子:

a:not(:hover) {
  text-decoration: none;
}

nav a:nth-child(n) {
  /* Works, but not ideal either */
  text-decoration: underline;
}


(or a:any-link(对于链路)
:where()所做的是允许您完全删除:hover添加的特性,从而更容易地为某些a元素覆盖此规则,例如,通过确保nav中的a元素始终带有下划线,而不管光标是否位于这些元素上(因为nav a比仅a更具体)。
由于:where()降低了选择器的特异性,因此通常会将:where()用于需要覆盖的选择器,而不是覆盖的选择器。另一方面,使用:is()只是为了减少CSS规则中的选择器重复,例如,通过更改

.span1-1:hover, .span1-2:hover


:is(.span1-1, .span1-2):hover


同时 * 保留 * 特异性(不过请注意,如果使用不同的特异性量对选择器进行分组,则:is()的工作方式会有所不同)。
这意味着,虽然:where():is()有着相似的语法,但实际上它们是两个不同的伪类,有着不同的用例。尽管如此,它们的用例还是有部分重叠。例如,在一般规则中,您可能需要减少选择器的重复,这意味着使用:is()。但是您更喜欢使用:where()来降低特异性,允许它接受一个选择器列表,这样就不必编写:where(:is(selector-list))了。这个原则适用于许多其他新的伪类,:host-context():has(),以及级别4 :not()

hwamh0ep

hwamh0ep2#

从我的评论
我猜这是选择器的特殊性,其中()将很容易被覆盖,离散,而()确实增加了特殊性,详细信息在这里https://developer.mozilla.org/en-US/docs/Web/CSS/:where
这里是你的片段中的示例

span {
  display: inline-block;
  height: 100px;
  width: 100px;
  background-color: grey;
  margin-bottom: 10px;
}

p :is(.span1-1, .span1-2):hover {
  background-color: firebrick;
}

div :where(.span2-1, .span2-2):hover {
  background-color: teal;
}

 .span2-1:hover, 
 .span1-2:hover {
  background-color: darkorange;
}

个字符
注意:我一开始使用了一个 Package 器来增加特殊性,并设置了两个不同的容器来分派测试。

ctzwtxfj

ctzwtxfj3#

为不熟悉CSS特性的人解释:is vs :where

特异性用3个数字表示,形式为ID-CLASS-TYPE
举例来说:
#thing .my-class div具有特异性1-1-1
#thing .my-class div:hover具有特殊性1-1-2(伪类被认为是一种类型)
.my-class .my-other-class具有特异性0-2-0
#thing具有特异性1-0-0
div具有特异性0-0-1
为了确定CSS规则的优先级,需要比较规则的特殊性。将3个数字中的每一个与其他规则进行比较,让最左边的比较获胜。
例如,0-2-0战胜0-1-31-0-0战胜0-2-0
现在,为了回答这个问题,:is对于避免重复很有用,因此您可以将规则ul li, ol li写成:is(ul, ol) li
注意,:is本身并不作为一个伪类来计算规则的特殊性。
:where让你做与:is完全相同的事情,除了:where()括号内提到的规则不计入规则的特异性计算。
例如,:is(ul, ol) li的特异性为0-0-2,而:where(ul, ol) li的特异性为0-0-1
如果你发现自己处于需要考虑两个类似CSS规则的优先级的情况下,你只需要担心whereis的选择。
请注意,任何!important的使用都将优先于任何特异性比较。

相关问题