如何在SASS混合宏中条件性插入&选择器?
合并Sass混合宏:条件性使用&选择器
我当前的Sass代码能生成正确的CSS,但想减少重复代码——genProps和genPropsAmp两个混合宏逻辑完全一致,唯一区别是genPropsAmp用&作为选择器前缀。我尝试添加$amp: false参数,通过@if条件控制前缀(比如写@if $amp {&}.#{$class}-...),但不管是条件判断还是插值都没成功。有没有办法通过条件控制&的使用,只用一个混合宏?
原Sass代码
$max_size: 0; $sub_suffixes: '', 'q', 'h', 't'; $sub_divs: '', '.25', '.5', '.75'; @mixin genProps($class, $props, $val_prefix: r, $max_size: $max_size, $sub_suffixes: $sub_suffixes) { @for $i from 0 through $max_size { @each $sub_suffix in $sub_suffixes { .#{$class}-#{$i}#{$sub_suffix} { @each $prop in $props { #{$prop}: var(--#{$val_prefix}-#{$i}#{$sub_suffix}); } } } } } @mixin genPropsAmp($class, $props, $val_prefix: r, $max_size: $max_size, $sub_suffixes: $sub_suffixes) { @for $i from 0 through $max_size { @each $sub_suffix in $sub_suffixes { &.#{$class}-#{$i}#{$sub_suffix} { @each $prop in $props { #{$prop}: var(--#{$val_prefix}-#{$i}#{$sub_suffix}); } } } } } .root{ @include genProps(f, font-size, a); @include genPropsAmp(m, margin); }
目标生成CSS
/* without amp */ .root .f-0 {font-size: var(--a-0);} .root .f-0q {font-size: var(--a-0q);} /*...*/ /* with amp */ .root.m-0 {margin: var(--r-0);} .root.m-0q {margin: var(--r-0q);} /*...*/
解决方案
可以通过动态构建选择器字符串实现混合宏复用,具体修改如下:
$max_size: 0; $sub_suffixes: '', 'q', 'h', 't'; $sub_divs: '', '.25', '.5', '.75'; @mixin genProps($class, $props, $val_prefix: r, $max_size: $max_size, $sub_suffixes: $sub_suffixes, $amp: false) { @for $i from 0 through $max_size { @each $sub_suffix in $sub_suffixes { // 根据$amp参数生成选择器前缀:true时用&,否则为空 $selector_prefix: if($amp, '&', ''); // 拼接完整选择器,Sass会自动解析&的作用 #{$selector_prefix}.#{$class}-#{$i}#{$sub_suffix} { @each $prop in $props { #{$prop}: var(--#{$val_prefix}-#{$i}#{$sub_suffix}); } } } } } .root{ // 默认不使用&,生成后代选择器 @include genProps(f, font-size, a); // 传入$amp: true,生成父选择器拼接类 @include genProps(m, margin, $amp: true); }
说明
- 添加
$amp: false作为可选参数,默认生成后代选择器 - 用
if($amp, '&', '')动态生成选择器前缀,Sass会自动处理&的解析逻辑:- 当
$amp为true时,&.xxx会编译为父选择器直接拼接类(如.root.m-0) - 当
$amp为false时,.xxx会编译为后代选择器(如.root .f-0)
- 当
- 最终生成的CSS与原代码完全一致,同时实现了混合宏的复用
内容的提问来源于stack exchange,提问作者Daniel Robinson
相关产品推荐
相关产品推荐

