如何实现遇到非指定元素即停止的CSS通用兄弟选择器?
实现限定范围的CSS兄弟选择器
现有问题
目前CSS提供两种兄弟选择器,但都无法满足需求:
- 相邻兄弟选择器
h1 + div:仅选中h1紧随其后的第一个div - 通用兄弟选择器
h1 ~ div:选中h1之后所有div,包括后续其他标题下的div
需要实现一种中间效果:选中某个标题(如h1)之后的所有div,但遇到非div元素(如其他标题)立即停止选择。例如在以下结构中,仅选中每个h1之后、下一个非div元素之前的div:
<h1>header 1</h1> <div>content</div> <div>content</div> <h2>header 2</h2> <div>content</div> <div>content</div> <h1>header 1</h1> <div>content</div> <div>content</div>
限制条件:只能使用纯CSS,无法修改HTML或JS,所有元素处于同一层级,标题后的div数量不固定。
测试代码
初始CSS(无法满足需求)
h1 ~ div{ color: red; } h2 ~ div{ color: purple; } h3 ~ div{ color: orange; } .container{ display:inline-block; border: 1px solid black; padding: 10px }
测试HTML
<div class="container"> -- 标题按h1-h3顺序排列时表现正常 -- <h1>H1</h1> <div>content</div> <div>content</div> <h2>H2</h2> <div>content</div> <div>content</div> <h3>H3</h3> <div>content</div> <div>content</div> </div> <div class="container"> -- 期望颜色顺序:橙色、红色、紫色、橙色 -- <h3>H3</h3> <div>content</div> <div>content</div> <h1>H1</h1> <div>content</div> <div>content</div> <h2>H2</h2> <div>content</div> <div>content</div> <h3>H3</h3> <div>content</div> <div>content</div> </div>
解决方案
利用CSS的:not()和:is()伪类实现范围限定,核心思路是:先选中标题后的所有div,再排除掉后续其他标题之后的div。
最终CSS代码
/* 选中h1之后、下一个h2/h3之前的所有div */ h1 ~ div:not(:is(h2, h3) ~ div) { color: red; } /* 选中h2之后、下一个h1/h3之前的所有div */ h2 ~ div:not(:is(h1, h3) ~ div) { color: purple; } /* 选中h3之后、下一个h1/h2之前的所有div */ h3 ~ div:not(:is(h1, h2) ~ div) { color: orange; } .container{ display:inline-block; border: 1px solid black; padding: 10px }
代码说明
:is(h2, h3) ~ div:匹配所有在h2或h3之后的div,我们用:not()排除这些div,剩下的就是h1之后、下一个h2/h3之前的div。- 兼容性处理:如果需要兼容不支持
:is()的旧浏览器,可以将选择器展开:h1 ~ div:not(h2 ~ div):not(h3 ~ div) { color: red; } - 扩展性:如果页面中还有其他非div的分隔元素(如
p、h4等),只需将这些元素加入:is()的参数列表即可。
内容的提问来源于stack exchange,提问作者Matte Crystal
相关产品推荐
相关产品推荐

