At規則のネストが起こる可能性

At規則は無限にネストできる。しかし現実的にネストが起こる可能性としては@media@supportsが相手を子に持つ場合だけだろう。そのネストはどういう目的を持って起こるのだろうか。

@media (max-width: 30em) {
  .foo {
    position: absolute;
  }

  @supports (position: sticky) {
    .foo {
      position: sticky;
    }
  }
}

ひとつはこのようにプログレッシブ・エンハンスメントを実装する手段として使うパターンだ。とりあえずA、より優れたBの実装があるならB、というようなCSSになる。普通にCSSを書きつつ、条件付きで分岐させるためフィーチャー・クエリーが子になる(なりうる)。

@supports (display: flex) {
  .foo {
    display: flex;
  }

  @media (min-width: 60em) {
    .bar {
      order: 1;
    }
  }
}

もうひとつはこのような、実装があるかによって0か1かになるパターンだ。実装がなかったら何もしない、というCSSになる。おおまかにフィーチャー・クエリーで分岐し、その中で普通のCSSを書いていくため、メディア・クエリーが子になる。

前者と後者を組み合わせる可能性はなくもない。しかし現実としてそのようなCSSを設計・運用するのはかなり難しいだろう。それこそあらゆるルールセットで逐一@supportsを書く羽目になりかねない。適切にベースラインを設定してある程度見切った方が安全で確実なCSSになる。


後者の@supports内に‘@media`がくるパターンは以下のように書いても等価だ。

@supports (display: flex) {
  .foo {
    display: flex;
  }
}

@media (min-width: 60em) {
  @supports (display: flex) {
    .bar {
      order: 1;
    }
  }
}

つまり分割してネストをひっくり返せる。CSS MQPackerではネスト可能性を考慮して、@mediaを常にルート直下になるように調整してからまとめるような実装にしつつある。可能性と効率を優先し、CSSの構造は大きく変えることにした。

そろそろメディア・クエリーをまとめる意味合いも下がってきた。これくらいの単純な実装で済ませておき、これが効果的でなくなったらCSS全体の設計を見直すべきだと考えている。