一般是不建议用@extend,如果你已经非常肯定要用@extend,那么再看看下面三条建议:

  1. Please reconsider.
  2. Use the placeholder hack(Extending silent classes in Sass).
  3. Keep an eye on your output.

理论上@extend是很不错,但在实践中,有太多事可能出错了。

I have seen stylesheets more-than-double in size; I have seen source order get destroyed; and I have seen clients plough right through their 4095 selector budget. It is always better to err on the side of caution and omit any features or tools that have the potential to cause so much trouble with little or no tangible gain. Having to shard your stylesheets into less-than-4096-selector-groups as a result of misusing a productivity tool is very, very counterintuitive.

When to use @extend

但你还是想用@extend怎么办,那我们来看看什么时候能用吧:

在明确相关联的规则集中共享相同的特征时,可以用@extend,例如:

.btn,
%btn {
    display: inline-block;
    padding: 1em;
}

.btn-positive {
    @extend %btn;
    background-color: green;
    color: white;
}

.btn-negative {
    @extend %btn;
    background-color: red;
    color: white;
}

.btn-neutral {
    @extend %btn;
    background-color: lightgray;
    color: black;
}

我们能得到:

.btn,
.btn-positive,
.btn-negative,
.btn-neutral {
    display: inline-block;
    padding: 1em;
}

.btn-positive {
    background-color: green;
    color: white;
}

.btn-negative {
    background-color: red;
    color: white;
}

.btn-neutral {
    background-color: lightgray;
    color: black;
}

这是一个很好的例子,这些规则在本质上是关联的,它们共享这相同的特征,而不是凑巧的。进一步,我们不移植他们的选择器远离他们的来源数百行,所以我们的特异性图保持好和理智。

When to use a mixin

听说过DRY原则吧,DRY就是Don‘t Repeat Yourself,关于DRY有几句话,是这样说的

you are generating repetition without actually repeating yourself. This is quite a subtle but important distinction to be aware of. Repetition in a compiled system is not a bad thing: repetition in source is a bad thing.

所以在代码里尽量不要DRY,编译器重复是没问题的。

对于你写的规则集中,肯定有很多代码是重复的,但是它们有很多是没有什么关联的,也就是说不能用@extend,那么我们就应该使用mixin了,来看个例子:

.foo {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

...

.bar {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

...

.baz {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

在上面的代码中,font-weight: 700;重复了很多遍,同时可以很明显的看到这些规则集都没什么联系,又放在文件中的不同位置,我们用mixin来改一下代码:

@mixin webfont() {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

...

.foo {
    @include webfont();
}

...

.bar {
    @include webfont();
}

...

.baz {
    @include webfont();
}

是的,编译结果和第一个一样,都是重复的font-weight,但是,我们在代码里没有重复,同时这样做也方便修改代码。有一点要记住,这些是没联系的,我们一定不要让他们变得有联系。它们只是凑巧有些共同的特征,但毫无联系,我们这样做只是为了减少代码重复。

mixin还可以传参数,如下:

@mixin truncate($width: 100%) {
    width: $width;
    max-width: 100%;
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.foo {
    @include truncate(100px);
}

Doyle
844 声望16 粉丝

前端, angular, vue


引用和评论

0 条评论