Sass伪类选择器嵌套:如何在:not中使用:first-of-type?
失效核心原因
你写的代码不生效,本质是对:first-of-type的匹配规则理解有偏差::first-of-type是在同标签名的所有兄弟节点里选第一个标签节点,它不会先执行.a-todo:not(.hidden)的条件把不符合的节点筛掉,再从筛好的列表里选第一个。
举个最常见的踩坑场景:
<li class="a-todo hidden">被隐藏的待办</li> <li class="a-todo">第一个可见待办(本来你想给它加圆角)</li> <li class="a-todo">第二个可见待办</li>
按你原来的选择器逻辑,:first-of-type匹配到的是整个列表里第一个li——也就是那个带.hidden的节点,这个节点刚好被:not(.hidden)排除,根本选不中,自然圆角不会加上。
修复方案
方案1:纯CSS无结构调整(兼容性拉满)
利用通用兄弟选择器的逻辑实现精准选中第一个符合条件的元素:先给所有带.a-todo、不带.hidden的元素加顶部圆角,再把“前面已经出现过同条件元素”的节点的顶部圆角清零,剩下保留圆角的就是目标第一个元素。修改后的Sass代码:
.a-todo:not(.hidden) { // 先给所有可见待办加顶部圆角 border-top-right-radius: 4px; border-top-left-radius: 4px; // 去掉前面已经有可见待办的后续节点的顶部圆角 &:is(.a-todo:not(.hidden) ~ &) { border-top-right-radius: 0; border-top-left-radius: 0; } }
这个逻辑不会被前面带.hidden的同标签节点干扰,完全匹配“选第一个不带.hidden的.a-todo”的需求。
方案2:工程场景最稳妥方案
如果是用框架渲染待办列表的场景,可以直接在渲染逻辑里判断:当前待办如果是第一个不带hidden类的节点,就给它加个专属修饰类(比如a-todo--first-visible),直接针对类写圆角样式。这种方式完全不依赖伪类的匹配逻辑,不会出现伪类规则的认知偏差,也没有兼容问题。
踩坑提醒:像
:first-of-type、:first-child、:nth-child这类带位置属性的伪选择器,规则都是先按DOM位置、标签名确定候选节点,再匹配前面的类选择器条件,不是先按类筛选节点再匹配位置,很容易写出逻辑和预期不符的选择器。
内容的提问来源于stack exchange,提问作者noiseymur

