如何用CSS :has选择器选取特定前置父元素下的.cell-rich?
我需要选择带有.parent父元素的.cell-rich元素,但这个.parent必须紧挨着位于另一个包含.cell-featured元素的.parent之前。尝试了下面的CSS选择器但无效,想知道在不给父容器添加额外类名的情况下,纯CSS能不能实现这个需求?
尝试的CSS代码
.parent:has(.cell-rich) + .parent:has(.cell-featured) > .cell-rich { padding-bottom: 0; }
示例HTML代码
<div class="parent"> <div class="cell-rich"></div> </div> <div class="parent"> <div class="cell-rich"></div> <!-- 仅希望给这个元素设置padding-bottom:0 --> </div> <div class="parent"> <div class="cell-featured"></div> </div> <div class="parent"> <div class="cell-rich"></div> </div>
编辑补充
我在浏览器开发者工具中测试发现,使用以下代码时:
.parent:has(.cell-rich) + .parent:has(.cell-featured) { padding-bottom: 0; }
样式实际应用到了.parent:has(.cell-featured),而非.parent:has(.cell-rich)。
解答
CSS目前没有反向相邻兄弟选择器,也就是无法直接选中某个元素的前一个兄弟元素。你之前的选择器.parent:has(.cell-rich) + .parent:has(.cell-featured)遵循CSS选择器“从左到右匹配”的规则,它选中的是紧跟在含.cell-rich的.parent之后的含.cell-featured的.parent,所以样式会作用在这个后续的.parent上,而非你需要的前一个.parent下的.cell-rich。
在不添加额外类名的前提下,纯CSS无法直接实现你的需求。如果必须实现,有两种可行方案:
使用JavaScript处理:
遍历页面中所有包含.cell-featured的.parent元素,找到它们的前一个兄弟元素。如果前一个兄弟是包含.cell-rich的.parent,就给该兄弟内部的.cell-rich设置样式。示例代码:document.querySelectorAll('.parent:has(.cell-featured)').forEach(el => { const prevSibling = el.previousElementSibling; if (prevSibling?.classList.contains('parent') && prevSibling.querySelector('.cell-rich')) { prevSibling.querySelector('.cell-rich').style.paddingBottom = '0'; } });调整HTML结构(若允许):
若能调整元素顺序,将需要修改样式的.cell-rich所在的.parent放在含.cell-featured的.parent之后,再利用正向兄弟选择器实现,但这显然不符合你的原始需求场景。
内容的提问来源于stack exchange,提问作者eyyMinda

