Sassとネイティブ ネスティング

2023年3月29日投稿者:Natalie Weizenbaum

本日リリースされるChrome 112の安定版は、新しいネイティブCSSネスティング機能をサポートする最初の安定版ブラウザです。この機能は、Sassのネスティングに触発されたもので、プレーンなCSSでスタイルルールをネストする機能を追加し、親 セレクタを参照するためにSassの慣例である&も使用します。

ここSassHQでは、私たちの言語設計がCSS自体の改善に繋がるたびに光栄に思っています。より多くのブラウザがこの機能のサポートを継続的に展開することで、ネスティングの使いやすさと明確さがより多くのCSS作者にもたらされることを楽しみにしています。

Sassのネスティングの未来Sassのネスティングの未来 パーマリンク

しかし、これは重要な疑問を提起します。Sassのネスティングはどうなるのでしょうか?まず第一に、既存の有効なSassコードが、広く使用されているブラウザと互換性のないCSSを出力するように変更することはありません。つまり、Sassのネスティングを段階的に廃止し、代わりにプレーンなCSSネスティングのみを出力することにしたとしても、グローバルブラウザ市場シェアの98%がネイティブ ネスティングをサポートするまでは実行しません。

さらに重要なことに、ネイティブCSSネスティングはSassネスティングと微妙な互換性がないのです。これは3つの異なる ケースに影響します。

  1. ネイティブCSSネスティングは、親セレクタを:is()で暗黙的にラップしますが、Sassはそのテキストを解決されたセレクタにコピーします。つまり 

    .foo, #bar {
      .baz { /* ... */ }
    }

    Sassでは.foo .baz, #bar .bazというセレクタが生成されますが、ネイティブCSSでは:is(.foo, #bar) .bazとなります。これにより、特異性が変化します。:is()は常に最も具体的なセレクタの特異性を持つため、:is(.foo, #bar) .baz

    <div class=foo>
      <p class=baz>
    </div>

    ネイティブCSSでは特異性1 0 1、Sassでは0 0 2でマッチしますが、どちらの要素も IDにはマッチしません。

  2. また、ネイティブCSSネスティングが:is()を使用しているため、子孫結合子を持つ親セレクタは異なる動作を します。

    .foo .bar {
      .green-theme & { /* ... */ }
    }

    Sassではセレクタ.green-theme .foo .barが生成されますが、ネイティブCSSでは.green-theme :is(.foo .bar)が生成されます。これは、ネイティブCSS版では マッチする

    <div class=foo>
      <div class="green-theme">
        <p class=bar>
      </div>
    </div>

    が、.fooにマッチする要素が.green-themeにマッチする要素の外にあるため、Sassではマッチしないことを意味します。

  3. SassのネスティングとネイティブCSSのネスティングはどちらも&fooのような構文をサポートしていますが、意味が異なります。Sassでは、これは親セレクタにサフィックスを追加します 。つまり、

    .foo {
      &-suffix { /* ... */ }
    }

    セレクタ.foo-suffixを生成します。しかし、ネイティブCSSでは、これは親セレクタに型セレクタを追加します 。つまり、

    .foo {
      &div { /* ... */ }
    }

    セレクタdiv.fooを生成します(Sassでは代わりに.foodivを生成します)。ネイティブCSSネスティングには、Sassのようにセレクタにサフィックスを追加する方法はありません 

設計上のコミットメント設計上のコミットメント パーマリンク

この新しいCSS機能の処理方法を検討する際、留意すべき2つの重要な設計上のコミットメントがあります 

  • 私たちはCSSスーパーセットであることにコミットしています。実際のブラウザでサポートされているすべての有効なCSSは、Sassでも同じ セマンティクスで動作する必要があります。

  • 私たちは下位互換性にコミットしています。可能な限り、既存のスタイルシートのセマンティクスを変更することを避けたいと考えており、そうする必要がある場合は、変更を円滑に行うためにできる限り多くの時間とリソースをユーザーに提供したいと考えています 

ほとんどの場合、CSSスーパーセットであり続けることが、下位互換性よりも優先されます。ただし、ネスティングは最も古く、最も広く使用されているSass機能の1つであるため、特に、ネイティブ CSSにエレガントな同等物がない&-suffixのような広く使用されている機能のサポートを落とすような変更には特に抵抗があります。

Sassの計画Sassの計画 パーマリンク

短期的には、Sassのネスティングについて何も変更する予定はありません。Sassは、既存のSass の動作と完全に互換性のある方法で実行できる場合を除き、プレーンなCSSネスティングをサポートしません。

.cssファイルでのプレーンなCSSネスティングの解析サポートは追加します。このネスティングはどのような方法でも解決されません。Sassは単にそのまま 出力します。

長期的には:is()がグローバルブラウザ市場シェアの98%でサポートされたら、Sassのネスティングを解決する際に:is()を出力するようにSassの移行を開始します。これにより、最初の2つの動作の非互換性において、SassはCSSのように動作するようになります。これを破壊的な変更とみなし、既存のスタイルシートを予期せず破壊することを避けるために、メジャーバージョンリリースの一部としてリリースします。Sass Migratorを使用して、この移行を可能な限りスムーズに行うように最善を尽くします。

私たちは、CSSとの互換性が高い、同等に人間工学に基づいた表現方法を思いつかない限り、&-suffixの現在の動作を破棄しません。この動作は既存のSassユーザーにとって非常に重要であり、プレーンなCSSバージョンのメリットは、それを上書きするほど強力ではありません