鍍金池/ 教程/ HTML/ 擴(kuò)展
簡(jiǎn)介
語(yǔ)法格式
循環(huán)
響應(yīng)式設(shè)計(jì)和斷點(diǎn)
擴(kuò)展
條件語(yǔ)句
結(jié)構(gòu)
注釋
工具
混合宏
變量
命名約定
警告和錯(cuò)誤
總結(jié)概要

擴(kuò)展

@extend 指令是 Sass 中既強(qiáng)大易于誤解的指令。該指令作為一個(gè)警示,告知 Sass 對(duì)選擇器 A 的樣式化正好存在與選擇器B共通的地方。不用多說(shuō),這是書(shū)寫(xiě)模塊化 CSS 的好助手。

實(shí)際上,@extend 的實(shí)際作用是維護(hù)繼承前后選擇器之間的。這也就是說(shuō):

  • 選擇器是受限的(比如:在 .foo > .bar.bar 必須有一個(gè)父級(jí) .foo);
  • 選擇器所收到的限制會(huì)傳遞給后續(xù)繼承的選擇器上(比如 .baz { @extend .bar; } 會(huì)生成 .foo > .bar, .foo > .baz);
  • 被繼承的選擇器會(huì)被要繼承的選擇器匹配。

要理解這些現(xiàn)象,最直接的方式就是看看當(dāng)沒(méi)有限制時(shí)繼承樣式所產(chǎn)生的選擇器數(shù)量劇增的結(jié)果。如果 .baz .qux 繼承了 .foo .bar,那么就會(huì)生成 .foo .baz .qux.baz .foo .qux,這是因?yàn)?.foo.baz 是常見(jiàn)的選擇器,它們可以成為父級(jí)、祖父級(jí)等等。

始終使用選擇器占位符定義選擇器之間的關(guān)系,而不是類名,這能讓你更加輕松地更換命名約定。此外,因?yàn)檫x擇器之間的關(guān)系只被定義在了占位符中,所以很少會(huì)產(chǎn)生意料之外的選擇器。

當(dāng)繼承 .class%placeholder 時(shí),如果父類和子類是同一類型,那么建議只使用 @extend 來(lái)實(shí)現(xiàn),比如 .error.warning 的一種,那么 .error 就可以通過(guò) @extend .warning 來(lái)實(shí)現(xiàn)。

%button {
  display: inline-block;
  // … button styles

  // Relationship: a %button that is a child of a %modal
  %modal > & {
    display: block;
  }
}

.button {
  @extend %button;
}

// Yep
.modal {
  @extend %modal;
}

// Nope
.modal {
  @extend %modal;

  > .button {
    @extend %button;
  }
}

擴(kuò)展選擇器在許多情境下是有用和值得的。始終牢記下面這些規(guī)則,謹(jǐn)慎使用 @extend 指令:

  • 優(yōu)先繼承 %placeholders,而不是具體的選擇器;
  • 當(dāng)繼承 .class 時(shí),只繼承單一的 .class,不要使用[復(fù)雜選擇器]complex selector;
  • 盡可能少的繼承自 %placeholders;
  • 避免繼承常見(jiàn)的父類選擇器(比如: .foo .bar)或者是常見(jiàn)的相鄰選擇器(比如:.foo ~ .bar),否則會(huì)讓選擇器的數(shù)量急速增加。

通常來(lái)說(shuō),@extend 有助于減少文件體積大小,因?yàn)樗牟僮鞅举|(zhì)上是合并選擇器而不是賦值樣式。話雖如此,當(dāng)你使用 Gzip 壓縮文件時(shí),@extend 對(duì)于文件壓縮的好處幾乎是可以忽略的。

這也就是說(shuō),如果你不能使用類似 Gzip 的工具,那么就可以考慮使用 @extend 來(lái)減少不必要的重復(fù),特別是當(dāng)樣式文件的大小成為性能瓶頸的時(shí)候,這種方式尤為有效。

繼承和媒體查詢

應(yīng)該只在同一個(gè)媒體查詢作用域下繼承選擇器,將媒體查詢視為一種對(duì)作用域的限制。

%foo {
  content: 'foo';
}

// Nope
@media print {
  .bar {
    // This doesn't work. Worse: it crashes.
    @extend %foo;
  }
}

// Yep
@media print {
  .bar {
    @at-root (without: media) {
      @extend %foo;
    }
  }
}

// Yep
%foo {
  content: 'foo';

  &-print {
    @media print {
      content: 'foo print';
    }
  }
}

@media print {
  .bar {
    @extend %foo-print;
  }
}

有關(guān) @extend 的好與壞,開(kāi)發(fā)者們之間的觀點(diǎn)大有不同,你可以閱讀以下文章了解其中的利弊:

總而言之,我建議只將 @extend 用于維護(hù)選擇器之間的關(guān)系。如果兩個(gè)選擇器是類似的,那么最好使用 @extend;如果它們之間沒(méi)有關(guān)系,只是具有相同的樣式,那么使用 @mixin 會(huì)更好。更多有關(guān)兩者的用法,請(qǐng)看這篇文章:When to use extend and when to use a mixin.

感謝 David Khourshid 對(duì)本節(jié)提供的技術(shù)支持。

上一篇:注釋