後ろで定義したセレクターも@extendで参照できる

Sassの@extendではてっきり@extendするまでに参照するセレクターを定義しておかなければならないと思い込んでいた(変数はそうなので)んだけど、そんなことはなかった。どこに書いたセレクターでも、例えファイルをまたがっていても@extendできる。

.bar {
  @extend %foo;
}

.buz {
  @extend %foo;

  margin-left: 3em;
}

%foo {
  margin: 2em 0 0 0;
}

というように書くと、

.buz {
  margin-left: 3em; }

.bar, .buz {
  margin: 2em 0 0 0; }

となる。この例だと.buzmargin-left: 3em0で上書きされる。言ってることがわかるけど、意味あるのかみたいな感じだけど、メディア・クエリを使ったセレクターを@extendするようなケースで役に立つような立たないような。


狭い画面ではインデントしないけど広い画面ではインデントするみたいな引用のCSSを書いてて、そのインデントのサイズを他でも使うのでプレースホルダー・セレクターにまとめようとした時にこう書いた。

%default-indent {
  @media (min-width: 800px) {
    margin-left: 3em;
  }
}

blockquote {
  @extend %default-indent;

  margin-left: 0;
}

これだと、

@media (min-width: 800px) {
  blockquote {
    margin-left: 3em; } }

blockquote {
  margin-left: 0; }

となるので、メディア・クエリで指定したmargin-left: 3emは上書きされる。プレースホルダー・セレクターを後に書いてやると、

blockquote {
  @extend %default-indent;

  margin-left: 0;
}

%default-indent {
  @media (min-width: 800px) {
    margin-left: 3em;
  }
}

で、

blockquote {
  margin-left: 0; }

@media (min-width: 800px) {
  blockquote {
    margin-left: 3em; } }

と意図通りの適用されるCSSになる。


ただこれを使いはじめるとプレースホルダー・セレクターがいろんな場所に散在するようになりやすく、とてつもなく読みづらいコードになる(った)ので、最終手段として頭の片隅に追いやっておくことにした。どうにもできなかったCSSハックの類いを最後にまとめてプレースホルダー・セレクターとして書いておいて、CSSハックを使う所で@extendするとかそういう使い方をするのは良さそう。CSSハックを使っているコードを混ぜることなく、CSSハックを使っていることを明示できる。