:where() 和 :is() 有什么区别?
What is the difference between :where() and :is()?
CSS最近添加了伪类:where()
和:is()
,我不知道什么时候用哪个。两者都可以用于 select 多个元素。这是一个片段,其中使用伪 类:
实现了相同的效果
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;
}
<span class="span1-1"></span>
<span class="span1-2"></span>
<br>
<span class="span2-1"></span>
<span class="span2-2"></span>
谁能举例说明他们之间的行为不同?
来自我的评论
I guess it is the spécifity of the selector, where() will easily be override, be discret while is() do increase the specifity,. details here 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;
}
<p><span class="span1-1"></span>
<span class="span1-2"></span>
<br>
</p>
<div>
<span class="span2-1"></span>
<span class="span2-2"></span>
</div>
注意:我首先使用包装器来增加特异性,并设置了两个不同的容器来分派测试。
如前所述,区别在于特异性。 MDN, though not prominently for some reason. The spec 中提到了这一点,另一方面,它更明确:
4.4. The Specificity-adjustment Pseudo-class: :where()
The Specificity-adjustment pseudo-class, :where()
, is a functional pseudo-class with the same syntax and functionality as :is()
. Unlike :is()
, neither the :where
pseudo-class, nor any of its arguments contribute to the specificity of the selector—its specificity is always zero.
有哪些用例?好吧,在您给出的示例中,它并不是很有用。您没有任何需要匹配或不覆盖特异性的竞争选择器。你有一个基本的 span
规则,和一个自然覆盖它的 :hover
规则(即仅通过特异性如何工作以及特异性最初设计的目的)。如果您不需要考虑任何特殊或例外的样式,那么使用 :is()
还是 :where()
.
并不重要
:where()
当您有更通用的规则但具有不必要的特定选择器时变得有用,并且这些规则需要被具有较少特定选择器的更专业的规则覆盖。 MDN 和规范都包含一个(非常)常见用例的示例——我不想简单地重复 what's on MDN,所以这是来自规范的示例:
Below is a common example where the specificity heuristic fails to match author expectations:
a:not(:hover) {
text-decoration: none;
}
nav a {
/* Has no effect */
text-decoration: underline;
}
However, by using :where()
the author can explicitly declare their intent:
a:where(:not(:hover)) {
text-decoration: none;
}
nav a {
/* Works now! */
text-decoration: underline;
}
与 MDN 不同,该规范并没有真正用英语解释这个用例,所以我会。这里的“作者期望”是 nav a
CSS 规则(我称之为专门规则)将覆盖 a:not(:hover)
规则(我称之为一般规则)。表面上看,这不会发生。
因为 :hover
伪 class 比类型选择器更具体,任何只有类型选择器的规则将无法覆盖适用的通用 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;
}
(或 a:any-link
,在链接的情况下)
:where()
所做的是允许您完全删除 :hover
添加的特殊性,从而更容易覆盖某些 a
元素的此规则,例如通过确保a
中的 nav
元素总是带有下划线,无论光标是否在它们上面(因为 nav a
比 a
更具体)。
不寻常的是,因为它 降低了 选择器的特异性,所以您通常将 :where()
用于需要覆盖的选择器,而不是覆盖选择器。另一方面,您使用 :is()
只是为了减少 CSS 规则中的选择器重复,例如通过改变
.span1-1:hover, .span1-2:hover
至
:is(.span1-1, .span1-2):hover
同时 保留 特异性(尽管请注意 :is()
does work differently once you're grouping selectors with different specificity amounts)。
这意味着虽然 :where()
具有与 :is()
相似的语法,但实际上它们是两个不同的伪 classes,具有不同的用例。尽管如此,它们的用例确实有部分重叠。例如,您可能需要减少一般规则中的选择器重复,这意味着使用 :is()
,但您更喜欢使用 :where()
来减少特异性。由于将单个 :where()
应用于多个选择器很有用,因此允许它接受选择器列表使得您不必编写 :where(:is(selector-list))
。此原理适用于许多其他新的伪class,例如:host()
、:host-context()
和:has()
,以及4级:not()
.
CSS最近添加了伪类:where()
和:is()
,我不知道什么时候用哪个。两者都可以用于 select 多个元素。这是一个片段,其中使用伪 类:
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;
}
<span class="span1-1"></span>
<span class="span1-2"></span>
<br>
<span class="span2-1"></span>
<span class="span2-2"></span>
谁能举例说明他们之间的行为不同?
来自我的评论
I guess it is the spécifity of the selector, where() will easily be override, be discret while is() do increase the specifity,. details here 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;
}
<p><span class="span1-1"></span>
<span class="span1-2"></span>
<br>
</p>
<div>
<span class="span2-1"></span>
<span class="span2-2"></span>
</div>
注意:我首先使用包装器来增加特异性,并设置了两个不同的容器来分派测试。
如前所述,区别在于特异性。 MDN, though not prominently for some reason. The spec 中提到了这一点,另一方面,它更明确:
4.4. The Specificity-adjustment Pseudo-class:
:where()
The Specificity-adjustment pseudo-class,
:where()
, is a functional pseudo-class with the same syntax and functionality as:is()
. Unlike:is()
, neither the:where
pseudo-class, nor any of its arguments contribute to the specificity of the selector—its specificity is always zero.
有哪些用例?好吧,在您给出的示例中,它并不是很有用。您没有任何需要匹配或不覆盖特异性的竞争选择器。你有一个基本的 span
规则,和一个自然覆盖它的 :hover
规则(即仅通过特异性如何工作以及特异性最初设计的目的)。如果您不需要考虑任何特殊或例外的样式,那么使用 :is()
还是 :where()
.
:where()
当您有更通用的规则但具有不必要的特定选择器时变得有用,并且这些规则需要被具有较少特定选择器的更专业的规则覆盖。 MDN 和规范都包含一个(非常)常见用例的示例——我不想简单地重复 what's on MDN,所以这是来自规范的示例:
Below is a common example where the specificity heuristic fails to match author expectations:
a:not(:hover) { text-decoration: none; } nav a { /* Has no effect */ text-decoration: underline; }
However, by using
:where()
the author can explicitly declare their intent:a:where(:not(:hover)) { text-decoration: none; } nav a { /* Works now! */ text-decoration: underline; }
与 MDN 不同,该规范并没有真正用英语解释这个用例,所以我会。这里的“作者期望”是 nav a
CSS 规则(我称之为专门规则)将覆盖 a:not(:hover)
规则(我称之为一般规则)。表面上看,这不会发生。
因为 :hover
伪 class 比类型选择器更具体,任何只有类型选择器的规则将无法覆盖适用的通用 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;
}
(或 a:any-link
,在链接的情况下)
:where()
所做的是允许您完全删除 :hover
添加的特殊性,从而更容易覆盖某些 a
元素的此规则,例如通过确保a
中的 nav
元素总是带有下划线,无论光标是否在它们上面(因为 nav a
比 a
更具体)。
不寻常的是,因为它 降低了 选择器的特异性,所以您通常将 :where()
用于需要覆盖的选择器,而不是覆盖选择器。另一方面,您使用 :is()
只是为了减少 CSS 规则中的选择器重复,例如通过改变
.span1-1:hover, .span1-2:hover
至
:is(.span1-1, .span1-2):hover
同时 保留 特异性(尽管请注意 :is()
does work differently once you're grouping selectors with different specificity amounts)。
这意味着虽然 :where()
具有与 :is()
相似的语法,但实际上它们是两个不同的伪 classes,具有不同的用例。尽管如此,它们的用例确实有部分重叠。例如,您可能需要减少一般规则中的选择器重复,这意味着使用 :is()
,但您更喜欢使用 :where()
来减少特异性。由于将单个 :where()
应用于多个选择器很有用,因此允许它接受选择器列表使得您不必编写 :where(:is(selector-list))
。此原理适用于许多其他新的伪class,例如:host()
、:host-context()
和:has()
,以及4级:not()
.