SCSS - 使用另一个@extend覆盖一个@extend

7

我在使用@extend时经常遇到的一个问题是,当尝试用另一个@extend覆盖继承属性时。

以下是一个示例:

// class selectors to be @extended
// these could also use % to be silent/placeholder selectors
.size-2xl {
    @include rem(font-size, 40px);
}
.size-3xl {
    @include rem(font-size, 60px);
}

// mapping the class selector properties onto some structural classes
.heading1 {
    @extend .size-3xl;
}
.heading1-small {
    @extend .heading1;
    @extend .size-2xl;
}

当SCSS被编译时,.heading1.heading1-small会获得正确的属性,但是.heading1-small看起来太大了。
这似乎是在将可扩展的类@extend映射到几个不同的选择器时发生的。
当SCSS被编译为CSS时,各种选择器被合并成一个或多个包含多个选择器的规则集。
有时,SCSS似乎被编译“无序”,因此编译的多个选择器.heading1会在.heading1-small之后输出。
这甚至可能是嵌套的@extend导致这种行为。
避免这种情况的最佳方法是什么?我能想到的一些事情是:
  1. 使用@include('size-2xl')(不那么DRY)
  2. 不要@extend包含@extend的规则(限制了@extend的使用)
谢谢。
1个回答

17
输出的CSS规则集与SCSS中定义的完全相同,只是你仅输出了扩展的.size-2xl.size-3xl规则集。因此,你需要交换这两个规则定义的位置(请参见演示),或将size规则定义为mixin并在header规则中包含它们(请参见演示)。所以,我觉得你可能对@extend的工作原理有些困惑。
如果你有类似以下的东西:
.class1 {
   foo: bar1;
}

.class2 {
   foo: bar2;
   @extend .class1;
}

您只需将选择器.class2添加到已存在的选择器.class1的规则集中 - 因此输出将如下所示:

.class1, .class2 {
   foo: bar1;
}

.class2 {
   foo: bar2;
}

然而,如果我们不添加任何新属性到.class2,仅仅使用@extend

.class1 {
   foo: bar1;
}

.class2 {
   @extend .class1;
}

.class2 的样式规则不会被打印到 CSS 中,只有选择器会被添加到 .class1 - 因此输出如下:

.class1, .class2 {
   foo: bar1;
}
这更或多或少是您正在做的事情,只是将选择器.header1. header2 添加到规则.size-2xl.size-3xl中,因此输出将位于在 SCSS 中定义这些规则的同一位置/顺序。 那么在您的示例中最终得到的结果是:
- 您定义了规则集.size-2xl.size-3xl - 您将.header1-small选择器添加到规则集.size-2xl中 - 您将.header1-small添加到.header1选择器中,并将两者都添加到规则集.size-3xl中 - 规则集.size-2xl(现在扩展为:.size-2xl, .header1-small)已打印到CSS中 - 规则集.size-3xl(现在扩展为:.size-3xl, .header1, .header1-small)已经打印到CSS中 - 规则集.header1(也是扩展的.header1, .header1-small)不会被打印出来,因为它没有任何定义的属性 - 规则集.header1-small不会被打印出来,因为它没有任何定义的属性
另一个注意事项:如果您使用占位符选择器(%),则也会发生同样的情况,只是可能更加混乱。例如,在.size-3xl,.header1,.header1-small中,.size-3xl 将是不可见的,但在CSS中整个内容仍将编译在 SCSS 中定义.size-3xl规则的位置。

谢谢,这是一个非常好的答案。现在我明白了如何构建扩展选择器,我可以看到为什么.size-3xl规则会覆盖.size-2xl规则,并且%占位符选择器不是解决这个问题的方法。似乎需要非常小心地使用@extend,并在预期变化时避免使用它(因为它很难“覆盖”)。我已经阅读了SMACSS和SMURF文献,后者只在模块内使用@extend。这似乎是更好的前进方式。您自己是否将@extend的使用限制为SMURF方法? - Dan
3
非常生动的例子。我总是很难理解@extend的用法。干杯,伙计! - BobbyZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接