使用扩展时出现奇怪的 SASS 输出

Strange SASS output when using extends

我有以下 SASS 个文件

_android.scss:

$width: 111px;
@import 'child';

.android .child {
    @extend %child;
}

_ios.scss:

$width: 999px;
@import 'child';

.ios .child {
    @extend %child;
}

_child.scss:

%child {
    width: $width;
}

app.scss:

@import 'ios';
@import 'android';

现在当我 运行 sass 我得到:

$> sass app.scss
.ios .child, .android .child {
   width: 999px; }

.ios .child, .android .child {
   width: 111px; }

不是我所期望的,这是

.ios .child {
    width: 999px;
}

.android .child {
    width: 111px;
}

我这里做错了什么?

这是因为 @extends 是按照它们在 sass 中首次找到的方式进行处理的,所有使用它们的选择器在那个时候都组合在一起(@extends 有点贪婪)并且你两次包含 @extends 占位符。

让我们逐步了解会发生什么:

  1. ios.sass 已加载,这会设置 $width 并包括 %child
  2. sass 由于包含而遇到占位符,因此它查看代码,获取该占位符的所有实例,对选择器进行分组并使用宽度的当前值。
  3. 加载下一个 android.sass,$width 设置为新值并再次包含 %child
  4. sass 重复步骤 2。每次遇到 @extends 时,它的所有实例都会分组并输出占位符中的值。

这就是为什么当您查看输出时会看到两个选择器被分组并且该组重复两次并定义每个 $width 值。

如何修复它

mixin 在这里最好。当遇到 mixin 时,它会在现场进行评估,并将生成的 属性 集注入选择器。

@mixin width($width-in: 1000px) {
    width: $width-in;
}

.ios .child {
    @include width(111px);
}

.android .child {
    @include width(999px);
}

现在,让我们逐步完成 mixin 示例

  1. mixin 已加载,sass 知道它,但不对其执行任何操作 - 将其视为等待调用的函数
  2. ios.sass 已加载并定义了选择器
  3. sass 看到调用带有参数的 mixin,所以它接受参数,使用 mixin 并将返回的宽度值注入选择器
  4. android.sass 已加载...
  5. sass 看到另一个对 mixin 的调用并重复该过程,将新的 width 值注入新的选择器。

PS 在我的 mixin 定义中,我使用默认值 1000px,如果调用 @include width(); 时将使用该默认值。