带同级选择器的SCSS Mixin嵌套使用失效问题求助
解决Sass嵌套选择器中Mixin的相邻兄弟选择器位置问题
问题核心
你编写的Mixin在非嵌套场景下能正常生成目标CSS,但嵌套使用时,相邻兄弟选择器~被错误地放到了整个选择器的最前端,导致选择器逻辑偏离预期——原本要选中.foo容器内非首个可见子元素的.bar,结果变成了选中跟在隐藏元素后的.foo .bar。
修正方案
问题出在not-first-child Mixin的选择器拼接逻辑上,需要把:not(...) ~插入到父选择器和目标子选择器之间,而不是整个选择器的开头。以下是两种可行的修正方式:
方式一:基于选择器拆分拼接
@mixin not-first-child { @at-root #{selector.unify(&, '*')} :not(.visually-hidden, .hidden) ~ #{selector.replace(&, selector.unify(&, '*') + ' ', '')} { @content; } } @mixin margin-top($spacing: $paragraph-spacing) { --margin-top-spacing: #{$spacing}; margin-bottom: 0; @include not-first-child { margin-top: var(--margin-top-spacing); } }
selector.unify(&, '*'):提取当前选择器的父级部分(比如嵌套场景中的.foo)selector.replace(...):提取当前选择器的子级部分(比如嵌套场景中的.bar)- 最终拼接成
父级 :not(...) ~ 子级的正确结构
方式二:用父/子选择器函数简化实现(需Sass 1.38+)
@mixin not-first-child { @at-root #{selector.nest(selector.parent(&), ':not(.visually-hidden, .hidden) ~ ' + selector.last(&))} { @content; } } @mixin margin-top($spacing: $paragraph-spacing) { --margin-top-spacing: #{$spacing}; margin-bottom: 0; @include not-first-child { margin-top: var(--margin-top-spacing); } }
selector.parent(&)直接获取当前选择器的父级selector.last(&)获取当前选择器的最后一级子选择器- 通过
selector.nest快速拼接出目标选择器结构
验证效果
嵌套场景测试
SCSS代码:
.foo { // some styles for .foo .bar { @include margin-top(1rem); } }
生成的CSS(符合预期):
.foo :not(.visually-hidden, .hidden) ~ .bar { --margin-top-spacing: 1rem; margin-bottom: 0; margin-top: var(--margin-top-spacing); }
非嵌套场景测试
SCSS代码:
.foo { @include margin-top(1rem); }
生成的CSS(保持原有正确逻辑):
:not(.visually-hidden, .hidden) ~ .foo { --margin-top-spacing: 1rem; margin-bottom: 0; margin-top: var(--margin-top-spacing); }
内容的提问来源于stack exchange,提问作者mrshowerman
相关产品推荐
相关产品推荐

