使用CSS :has(+)伪类定位前置兄弟元素失效的问题咨询
问题分析与修复方案
你的思路方向是对的——利用:has()结合相邻兄弟选择器+,来选中那些自身包含按钮链接、且紧跟的下一个<p>也带按钮链接的<p>元素,从而移除它的底部外边距。但规则没生效,可能是这几个原因:
1. 浏览器兼容性限制
虽然现在Chrome 105+、Firefox 121+、Safari 15.4+这些主流浏览器已经默认支持:has()选择器,但如果你的浏览器版本偏旧,或者在一些需要开启实验性特性的环境下,:has()可能无法正常工作。先确认下你的浏览器版本是否符合要求。
2. 选择器逻辑没问题,但需排查边距折叠问题
你的原始选择器逻辑是正确的,但可能因为CSS外边距折叠的特性,导致你看不到预期效果:就算第一个<p>的margin-bottom被设为0,第二个<p>的margin-top:2rem依然会保留,两个元素之间的间距还是2rem。
如果你的目标是让这两个带按钮的<p>之间没有间距,换个思路写法会更直观,也能避开边距折叠的混淆:
p { margin: 2rem; } /* 选中紧跟在带按钮链接的p后面的、同样带按钮链接的p,移除它的顶部外边距 */ p:has(a[class*="link--button"]) + p:has(a[class*="link--button"]) { margin-top: 0; }
快速验证选择器是否生效的小技巧
你可以给选中的元素加个显眼的边框,快速判断选择器是否匹配成功:
p:has(a[class*="link--button"]):has( + p:has(a[class*="link--button"])) { margin-bottom: 0; border: 2px solid red; /* 临时添加,看第一个p是否变红 */ }
如果边框出现,说明选择器已经生效,问题出在边距的表现上;如果边框没出现,那大概率是浏览器不支持:has()导致的。
另外你提到的那篇文章里的用法思路完全正确,:has()确实不止是“父选择器”,它能实现很多传统CSS做不到的上下文样式控制,包括这种基于后续元素来样式化当前元素的场景。
内容的提问来源于stack exchange,提问作者Georgios
相关产品推荐
相关产品推荐

