CSS选择器疑难:如何在嵌套容器中仅当第二个子元素为img时取消.deco元素的底部边距
嘿,我来帮你把这个问题理清楚!你的CSS选择器失效主要是因为选择器的逻辑和HTML结构不匹配,以及对:is()伪类的用法理解有偏差,咱们一步步拆解:
1. 你的选择器到底错在哪?
先看你写的选择器:
.pros-cons .column:nth-child(2):is(img) .deco
这个选择器的逻辑是:
找到
.pros-cons下的第二个子元素,这个元素必须同时是.column类,并且是<img>标签,然后选中它内部的.deco
但你的HTML里,.pros-cons的子元素是<div class="column">(是div不是img),而且.column的第二个子元素是<figure>,不是直接的<img>。这就导致这个选择器根本匹配不到任何元素,自然不会生效——哪怕你把img换成figure,逻辑还是错的,因为你是在要求.column本身是figure,而不是.column的子元素是figure。
2. 正确的选择器应该怎么写?
你的核心需求是:在.pros-cons的.column容器中,当该容器的第二个子元素是img/figure时,选中容器内的.deco并取消边距。
这里需要用到CSS Selectors Level 4的:has()伪类(它用来选择包含指定子元素的父元素),结合:is()来简化选择逻辑:
情况1:匹配.column的第二个子元素是<figure>
.pros-cons .column:has(:nth-child(2):is(figure)) .deco { padding-bottom: 0; margin-bottom: 0; }
情况2:匹配.column的第二个子元素内部包含<img>
如果你的需求是只要第二个子元素里有img就生效(不管外层是figure还是其他容器),可以写成:
.pros-cons .column:has(:nth-child(2) img) .deco { padding-bottom: 0; margin-bottom: 0; }
3. 关于伪选择器的合法性说明
:is()和:has()都是CSS Selectors Level 4的特性,并非CSS3,但现在主流浏览器(Chrome、Edge、Safari)都已经原生支持,Firefox需要手动开启layout.css.has-selector.enabled配置项才能使用。你的写法里的多个伪选择器组合本身是合法的,只是逻辑方向错了。
修复后的完整代码
CSS
.deco { padding-bottom: 1em; background-color: red; } /* 根据你的需求选择下面其中一个即可 */ /* 匹配第二个子元素是figure的情况 */ .pros-cons .column:has(:nth-child(2):is(figure)) .deco { padding-bottom: 0; margin-bottom: 0; } /* 匹配第二个子元素包含img的情况 */ /* .pros-cons .column:has(:nth-child(2) img) .deco { padding-bottom: 0; margin-bottom: 0; } */
HTML
<div class="pros-cons"> <div class="column"> <p class="deco"></p> <figure> <img src="your-image-url.jpg" alt="示例图片"> </figure> </div> </div>
内容的提问来源于stack exchange,提问作者Devon

