SASS @extend混合占位符与常规类时的插值问题求助
问题根源分析
你的问题出在同时将占位符和常规类放在同一个选择器列表中声明,导致$this: &捕获到的是一个包含%drawer和.drawer的选择器集合,而不是单个占位符选择器。当你用#{$this}插值时,这个集合会被完整展开,再结合@extend的替换逻辑,就生成了冗余且错误的选择器。
另外,&__optional-element没有在.product-drawer中输出,是因为它在原声明中会同时生成%drawer__optional-element和.drawer__optional-element,但你的.product-drawer只显式@extend了%drawer和%drawer__content,没有继承%drawer__optional-element,所以这部分样式不会被应用到.product-drawer__optional-element上。
解决方案:分离占位符与常规类,避免代码重复
你不需要重复代码,只需要让常规类.drawer继承占位符%drawer即可。这样既保留了直接使用.drawer的能力,又能让$this正确捕获单个占位符选择器,插值时不会出现混乱。
修改后的SASS代码如下:
// 定义纯占位符的基础样式 %drawer { $this: &; // 现在$this只捕获%drawer,而非选择器列表 position: fixed; z-index: 10; &__content { right: 0; transform: translate(100%, 0); } &__optional-element { background: red; } &--left { // 插值后会正确替换为扩展后的类名 #{$this}__content { left: 0; transform: translate(-100%, 0); } } } // 让常规类继承占位符,无需重复写样式 .drawer { @extend %drawer; } // 你的扩展代码保持不变,按需添加需要继承的嵌套元素 .product-drawer { @extend %drawer; &__content { @extend %drawer__content; } // 如果需要.product-drawer__optional-element,添加这一行 &__optional-element { @extend %drawer__optional-element; } }
编译后的正确CSS输出
.drawer, .product-drawer { position: fixed; z-index: 10; } .drawer__content, .product-drawer__content { right: 0; transform: translate(100%, 0); } .drawer__optional-element, .product-drawer__optional-element { background: red; } .drawer--left .drawer__content, .product-drawer--left .product-drawer__content { left: 0; transform: translate(-100%, 0); }
为什么这样可行?
$this的正确性:现在$this只绑定了%drawer,当.product-drawer继承%drawer时,所有#{$this}的引用都会被替换为.product-drawer,不会再混入.drawer的选择器。- 无代码重复:常规类
.drawer通过@extend %drawer复用所有样式,不需要复制粘贴任何规则。 - 清晰的继承关系:每个嵌套的元素(如
__content、__optional-element)都对应独立的占位符,你可以按需选择是否继承,完全符合你的HTML简洁性需求。
内容的提问来源于stack exchange,提问作者Filipe
相关产品推荐
相关产品推荐

