セレクターのネスト

Sass等のCSSプリプロセッサーではネストを使ってくだくだしい(単に長い)セレクターを意識することなく自然に書けてしまうので、あとでちょっとだけ上書きしようかなとか言う時に面倒なことになったりする。CSSのカスケーディングは魔窟だし!特にSassでは@extendでセレクターの順序が変わってハマるなどということもあるので、CSSの感覚にネストを組み合わせて書いていると簡単に破綻する。

つまりCSSプリプロセッサーによるセレクターの抽象化がCSSのセレクターの詳細度と順序を想像しづらくしてしまうということ。もちろんこれはCSSプリプロセッサー側の問題ではなく、ユーザー側がその抽象化プロセスをきちんと理解していないことが原因なんだけど。

また、セレクターのネストはHTMLのネストをそのまま再現するのに使ったりすると把握しやすいのだけど、それだとセレクターを書く手間が少し減る程度の利点しかない。ネストは関連したルールセットを1つにまとめるという形で主に使うと良い。例えば、今のこのWebサイトでは小見出しの直後の段落では余白を少なくするというようなデザインになっているが、SCSSのコードは以下のようになっている。

p {
  @extend %default-margin;

  h3 + &,
  h4 + &,
  h5 + &,
  h6 + & {
    @extend %mini-margin;
  }
}

こう書いた方が小見出しのセレクター(h3など)に対してネストして書くよりも、小見出しの直後の段落にフォーカスを当てたルールセットであることがわかりやすいはず。まだまだ僕も試行錯誤している途中なのでアレだけど、単に今まで空白区切りで書いていたセレクターをネストに書き換える……みたいなのは今直ぐ止めた方が良い。


CSSプリプロセッサーには、このネストであるとかベンダー拡張プリフィックスをまとめて生成であるとかそういう「便利なCSS」的な側面はもちろんある。けど、CSSプリプロセッサーのキモはそこではなくて、論理的にCSSを書くことができるようになるということにあると思う。例えばロゴのデザインとレイアウトを別々に定義して@extendで混ぜるとかが簡単にできるようになるということだったり、widthなどのプロパティーで使われる長さに意味を与えることができるということだったりする。

.foo {
  width: $column-span2; // 幅を2カラム分
}

.bar {
  margin-left: $sidebar-width + $gutter; // サイドバーとカラム間の幅だけ余白を確保
}

CSSプリプロセッサーで「CSSを効率良く簡潔に書ける」というのは間違ってはいないんだけど、その字面から想像できるようなものではない。