使用 CSS :has() 选择前一个兄弟姐妹
CSS 更令人抓狂的限制之一是长期以来它无法根据其子元素或前一个兄弟元素来选择元素。这使得构建可以针对元素的先前同级元素的 CSS 选择器变得不可能,但是has:()
伪类(以及来自选择器级别 4 的、 和)已经抛弃了旧的限制,并在使用时开辟了一个充满可能性的:not()
新世界选择器。:where()
:is()
截至撰写本文时,所有主要浏览器(包括 Chrome 和 Safari)都:has()
支持它,但 Firefox 是一个明显的例外。84.68%
对 Firefox 的实验性支持于 2022 年 7 月启动,可以通过标记启用- 您可以通过此 Bugzilla 问题layout.css.has-selector.enabled
跟踪进度。在此之前,如果您不针对或不支持 Firefox,或者使用polyfill ,则可以使用伪类。:has()
选择前一个兄弟#https://tobiasahlin.com/blog/previous-sibling-css-has/#selecting-the-previous-sibling
想象一下我们有一系列元素,如下所示:
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="circle"></div>
<div class="box"></div>
...我们想要选择圆圈之前的元素并为其设置样式。相邻同级组合器( +
) 可以选择紧随另一个元素的元素,我们可以将其与:has()
该元素组合以仅选择.box
紧随 a 的元素.circle
(或者从圆的角度来看,其前一个同级):
.box:has(+ .circle) {
width: 40px;
height: 40px;
}
您可以将此选择器视为首先 1) 选择所有框,然后 2) 将元素过滤为仅匹配模式“框 + 圆”的元素,这将仅返回圆的前一个同级元素。
选择前第 n 个兄弟#https://tobiasahlin.com/blog/previous-sibling-css-has/#selecting-the-nth-previous-sibling
可以使用相邻同级组合器来选择另一个之前的任何特定元素。我们可以使用两个相邻的同级组合器来选择前第二个同级:
.box:has(+ * + .circle) {
width: 40px;
height: 40px;
}
如果您愿意,您可以将选择器的范围等同于一个类(而不是笼统的*
)。在这个例子中,.box
兄弟姐妹:
.box:has(+ .box + .circle) {
width: 40px;
height: 40px;
}
这个选择器可能很难理解和解析。可以将其视为选择所有框 ( .box
),然后过滤这些元素,以便剩下的元素.box
与模式“self + box + Circle”匹配,这将只是前第二个同级元素。
如果你想选择前第三个同级,你可以使用三个相邻的同级组合器......
.box:has(+ * + * + .circle) {
width: 40px;
height: 40px;
}
…等等等等。+
您可以根据需要继续添加相邻同级组合器 ( ),以选择任意第 n 个前面的元素。
选择所有前面的兄弟姐妹#https://tobiasahlin.com/blog/previous-sibling-css-has/#selecting-all-preceding-siblings
如果要选择所有先前的同级元素,可以将:has()
伪类与通用同级组合器 ( ~
) 组合,只要第二个元素位于第一个元素之后,无论其位置如何,它都会匹配第二个元素:
.box:has(~ .circle) {
width: 40px;
height: 40px;
}
换句话说,只要本例中的 后面某个时刻.box
有 a ,就会选择 并设置样式。.circle
.box
选择除最相邻的兄弟姐妹之外的所有先前兄弟姐妹#https://tobiasahlin.com/blog/previous-sibling-css-has/#selecting-all-preceding-siblings- except-the-most-adjacent-sibling
最后,我们可以将通用同级组合器 ( ~
) 与相邻同级组合器 ( +
) 组合起来,并选择除最相邻的元素之外的所有前面的元素:
.box:has(~ * + .circle) {
width: 40px;
height: 40px;
}
.box
该选择器选择与“自身后跟任意点的框+圆圈”模式匹配的任何选择器。
需要注意的是,直到2022-09-02,chrome和edge 105版本才支持 :has() 选择器。