CSSの新機能カスケードレイヤーが主要ブラウザにサポートされます、最初に理解しておきたい基礎知識を解説

CSSの新機能「カスケードレイヤー」がいよいよ主要ブラウザすべてにサポートされます。カスケードレイヤー@layerを使用すると、CSSの詳細度とスタイルの順番をカスケード内で明示的にレイヤー化(階層化)でき、これまでのCSSの実装方法が大きく変わるものです。

Chromeのデベロッパーによるカスケードレイヤーの基礎知識を紹介します。

CSSの新機能カスケードレイヤー、最初に理解しておきたい基礎知識を解説

Cascade layers are coming to your browser
by Una Kravets

下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様のライセンスに準じて翻訳しています。

はじめに

カスケードレイヤー@layerCSSルール)は、Chromium 99、Firefox 97、Safari 15.4 Betaに搭載されるCSSの新機能です。
参考: CSS Cascading and Inheritance Level 5

【訳者注】先週リリースされたFirefox 97ではデフォルトでサポートされ、ChromeとSafariは次のバージョンでサポートされる予定です。
参考: Firefox, Chrome, Safari

カスケードレイヤーを使用すると、CSSファイルをより明示的に制御でき、スタイル固有の競合を防ぐことができます。これは大規模なコードベース、デザインシステムやアプリでサードパーティのスタイルを管理する場合に特に役立ちます。

CSSを明確な方法で階層化することで、スタイルの予期せぬオーバーライドを防ぎ、より良いCSSのアーキテクチャを促進します。

CSSの詳細度とカスケード

CSSの詳細度とは、CSSがどのスタイルをどの要素に適用するかを決定する方法です。使用できるさまざまなセレクタによってスタイルルールの詳細度が決まり、詳細度が高いほど優先(オーバーライド)されます。

たとえば、要素はclassセレクタよりも詳細度が低く、さらにidセレクタよりも低くなります。詳細度は、CSSを学ぶ上で欠かせません。BEMのようなCSSの命名規則があるのは、意図せずに詳細度が上書きされるのを防ぐためです。

すべてに単一のclass名を付けると、すべてが同じ詳細度の平面上に配置されます。しかし、特にサードパーティのコードやデザインシステムと連携する場合、このように整理されたスタイルを維持することは常に可能とは限りません。

BEMの命名規則の例

BEMの命名規則の例(すべてが同じ詳細度): keepinguptodate.com

カスケードレイヤーはこの問題を解決することを目的としています。CSSのカスケードに新しいレイヤーを導入するものです。レイヤー化されたスタイルでは、レイヤーの優先順位は常にセレクタの詳細度よりも高くなります。

たとえば、.post a.link.card aよりも高い詳細度を持っています。カード内、ポスト内でリンクのスタイルを設定しようとすると、より詳細度の高いセレクタが適用されることがわかります。

@layerを使用すると、それぞれのスタイルの詳細度をより明確にすることができ、すべてのCSSが同一平面上にある場合、数値的には詳細度が低くても、カード内リンクのスタイルがポスト内リンクのスタイルをオーバーライドできます。これは、カスケードの優先順位によるものです。レイヤー化されたスタイルは、新しいカスケード「プレーン」を作成します。

カスケードレイヤーの使用例

数値的には詳細度が低くても、オーバーライドできる

@layerの動作

@layerのデモ

デモページ

上記は、@layerを使用したカスケードレイヤーの威力を示したものです。classがないリンク、.linkがあるリンク、.pinkがあるリンクなど、リンクがいくつかあります。CSSには3つのレイヤー(base, typography, utilities)があります。

すべてのリンクはグリーンかピンクになります。CSSの仕組みを解説すると、.linkaよりも高いセレクタレベルの詳細度が高いですが、baseレイヤーよりも優先順位の高いtypographyレイヤーのaにカラーのスタイルがあります。グリーンのルールがブルーのルールの後のレイヤーにある場合、a { color: green }.link { color: blue }をオーバーライドします。

レイヤーの優先順位は要素の詳細度に勝ります。

レイヤーの優先順位の管理

上記のようにページの記述順でレイヤーの優先順位を管理することもできますし、ファイルの先頭で優先順位を定義することもできます。レイヤーの優先順位は、各レイヤー名がコード内で最初に表示されることで確定されます。

つまり、ファイルの先頭に下記を記述すると、リンクはすべてレッドで表示され、.linkのリンクはブルーで表示されます。

この1行のCSSを追加するだけで、レイヤーの優先順位は逆(utilitiesが最初で、baseが最後に)になります。baseレイヤーのスタイルは、typographyレイヤーのスタイルルールよりも常に高い詳細度も持つことになります。リンクのスタイルはグリーンではなく、レッドやブルーになります。

@layerのデモ

デモページ

ITCSS(逆三角形CSS)は、Harry Robertsが考案したCSSの手法で、オーバーライドや複雑さを最小限に抑えた理想的なスタイル構成ができるようにするためのものです。レイヤー化されたスタイルを構造化するための理想的な方法で、最小から最大へと、レイヤー化されたスタイルを記述する際に従うべき素晴らしい規則です。

インポートファイルの整理

@layerを使用する別の利点は、インポートファイルです。スタイルをインポートするときに、下記のようにlayer()関数で直接できます。

上記のCSSには、3つのレイヤー(base layouts components)があります。normalize、theme、typographyのファイルはbaseに、postファイルはlayoutsに、cardsとfooterはcomponentsに配置されています。これらのCSSファイルをインポートすると、layer()関数でレイヤーがインスタンス化されます。別の方法としては、ファイルの先頭でインポートする前に定義することもできます。

これで、レイヤー名の最初のインスタンスですでに確立されているので、スタイルを@importする順序はレイヤーの記述順とは関係ありません。これで心配事が一つ減りました。インポートしたファイルを特定のレイヤーに定義することはできますが、その順番はすでに確立されています。

@layerのデモ

デモページ

このようにCSSファイル内のスタイルを読み込むとチェーン化してしまうので、HTML内のstyleタグにすべてを含める方がパフォーマンス的に優れています。link経由で含めるスタイルシートは最もパフォーマンスが高いのですが、現在のところレイヤーとしてロードする機能はありません。これは現在、WHATWGの未解決課題となっています。

レイヤーとカスケード

ここで、レイヤーがどのように使用されるのか、カスケードとの関連性を見てみましょう。

レイヤーとカスケード

優先順位はこのようになっています。

  • User Agent normal (優先順位が最も低い)
  • Local User @layer
  • Local User normal
  • Author @layers
  • Author normal
  • Author !important
  • Author @layer !important
  • Local User !important
  • User Agent !important(優先順位が最も高い)

@layer !importantのスタイルが反転していることにお気づきでしょうか。レイヤーでない(通常の)スタイルよりも詳細度が低いのではなく、より高い優先順位になります。これは、!importantがカスケードでどのように機能するかによるものです。スタイルシートの通常のカスケードを中断し、通常のレイヤーレベルの詳細度(優先度)を逆転させます。

入れ子のレイヤー

レイヤーは、他のレイヤーの中に入れ子にすることもできます。下記は、Miriam SuzanneのCascade Layers explainerから得たCSSです。

このCSSでは、framework.defaultにアクセスするために、.を使用してframework内に入れ子になっているdefaultレイヤーを示すことができます。省略して下記のように記述することもできます。

レイヤーとレイヤーの順番は次のとおりです。

  • default
  • framework.default
  • framework 非レイヤー化
  • 非レイヤー化

Shadow DOM内にカプセル化されたレイヤーは、Shadow DOMの境界を越えることはありません。したがって、Shadow DOM内の同じ名前のレイヤーはLight DOM内のレイヤーの順番に影響を与えず、その逆も同様です。

カスケードレイヤーの注意点

カスケードレイヤーは正しく使えば素晴らしいものですが、混乱や予期せぬ結果を生む可能性もあります。カスケードレイヤーを使用する際には、以下の点に注意してください。

Rule 1: スコープに@layerを使用しない

カスケードレイヤーはスコープを解決するものではありません。たとえば、@layerを含むCSSファイル(card.cssのように)があり、すべてのリンクにスタイルを定義したい場合、次のようなCSSは記述しないでください。

上記のように定義すると、ファイル内のすべてのaタグにこのスタイルがオーバーライドで適用されます。スタイルのスコープを適切に設定することが重要であることに変わりはありません。

Rule 2: カスケードレイヤーは、レイヤー化されていないCSSの背後に配置される

ここで重要なのは、レイヤー化されたCSSファイルは、レイヤー化されていないCSSを上書きしないことです。これは、既存のコードベースと連携して、より理にかなった方法でレイヤーを導入しやすくするための意図的な決定です。たとえば、reset.cssを使用することはカスケードレイヤーの良い出発点で、使用例として適しています。

Rule 3: !importantはカスケードの詳細度を反転させる

レイヤー化されたスタイルはレイヤー化されていないスタイルよりも詳細度が低いですが、!importantを使用すると逆になります。レイヤーでは!importantルールを持つ宣言は、レイヤー化されていないスタイルよりも詳細度が高くなります。

!importantスタイルは、詳細度を反転させます。前述の図は、参考のためにこれを示しています: author @layersはauthor normalよりも優先順位が低く、author !importantよりも優先順位が低く、author @layer !importantよりも低くなっています。

複数のレイヤーがある場合、!importantがある最初のレイヤーが!importantの優先順位を取得し、最も詳細度の高いスタイルとなります。

Rule 4: インジェクションポイントを把握する

レイヤーの順番は、各レイヤー名が最初にコードに現れることで確立されるので、layer()のインポートと設定の後や別の@layer文の後に@layer宣言を記述しても無視されます。カスケードレイヤーの場合、ページ上で最後にあるスタイルルールが適用されるCSSとは異なり、最初のインスタンスで順番が確立されます。

これは、リスト、レイヤーブロック、インポートのいずれでも可能です。インポートリストの後にlayer()@layerを記述しても何も起こりません。しかしファイルの先頭に置くと、レイヤーの順番が設定され、アーキテクチャ内のレイヤーを明確に確認できるようになります。

Rule 5#: 詳細度に注意する

カスケードレイヤーでは詳細度の低いセレクタが詳細度の高いレイヤーにある場合、詳細度の低いセレクタ(aなど)が詳細度の高いセレクタ(.linkなど)より優先されます。

前述の例でみると、layer(components)内のaは、layer(utilities)内の.pinkをオーバーライドします(@layer utilitiescomponentsに指定されている場合)。これはAPIの意図的なものですが、予想外に混乱し、イライラする可能性があります。

そのため、ユーティリティのクラスを作成する場合は、常にオーバーライドするコンポーネントよりも上位のレイヤーとして記述してください。「色を変えるために.pinkを追加したのに、適用されない」ということがあるかもしれません。

カスケードレイヤーの参考リソース

カスケードレイヤーについては、下記のリソースも参照ください。

sponsors

top of page

©2022 coliss