カスケードレイヤー「@layer」でCSSの実装がどう変わるのか、仕組みと基礎知識、さまざまな使用例を徹底解説

CSSの新機能「カスケードレイヤー」がいよいよ主要ブラウザすべてにサポートされます。Firefox 97(先月リリース)とChrome 99(3/1リリース)でサポートされ、そしてSafariでは次期バージョンでサポートされる予定です。

カスケードレイヤー@layerを使用すると、CSSの詳細度とスタイルの順番をカスケード内で明示的にレイヤー化(階層化)でき、これまでのCSSの実装方法が大きく変わります。

カスケードレイヤーの仕組みと基礎知識、さまざまな使用例を紹介します。

CSSのカスケードレイヤー「@layer」の仕組みと基礎知識、さまざまな使用例を徹底解説

Hello, CSS Cascade Layers
by Ahmad Shadeed

CSSのカスケードレイヤーについて知識を得たい人は、下記の記事もお勧めします。

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

はじめに

CSSでよくある混乱の原因の1つは、スタイルを定義する際の詳細度です。たとえば、ある要素のdisplay値を変更しても、カスケード内の別の要素がより高い詳細度を持っているとオーバーライドされて、うまく機能しないことがあります。あるいは、別の要素に!importantがあるなどです。コードの量が増え、このような問題を防ぐ(あるいは減らす)方法でCSSを管理していない場合に起こります。

カスケードと詳細度の問題との戦いを克服するためには、特定のCSSブロックをどこに書くのか注意する必要があります。小さなプロジェクトなら簡単かもしれませんが、大規模なプロジェクトでは時間のかかる作業です。その結果、CSSをうまく管理して、その結果カスケードの問題を防ぐ(あるいは減らす)ためのさまざまな方法が見られるようになりました。私が思い浮かべたのは、BEM(Block, Element, Modifier)、Jonathan Snook氏のSmacss、Harry Roberts氏のInverted Triangle CSSの3つです。

この記事ではカスケードレイヤーの仕組みカスケードレイヤーでどのようにCSSを安心して書けるようになるのか、実際の使用例とともに解説します。

CSSでよくある問題

CSSの新機能「カスケードレイヤー」を使用する大きな利点は、詳細度や記述の順番を気にせずにCSSを記述できることです。例を挙げてみましょう。

2つのスタイルを持つボタン

2つのスタイルを持つボタン

デフォルトとghostの2つのスタイルを持つボタンがあります。HTMLは、非常にシンプルです。

もちろん、上記のHTMLはうまく機能します。しかし、3つ目のスタイルが必要になり、.button宣言の後にそれを記述できない場合はどうすればよいでしょうか。

3つのスタイルを持つボタン

3つのスタイルを持つボタン

.button.button--facebookの後にあるため、.button--facebookのスタイルはオーバーライドされてしまいます。

.buttonにオーバーライドされないようにするには、.button--facebookの詳細度を高くすることで回避できます。

もしくは下記でも回避できます(が、お勧めしません)。

どちらの解決方法も、それほど良いものではありません。ベストな方法は、.button宣言の直後の正しい場所に記述することです。CSSプリプロセッサ(例えばSassなど)の助けを借りて、CSSファイルをパーシャルとコンポーネントに分割せずに行うのは簡単な仕事ではありません。

CSSの新機能「カスケードレイヤー」とは

カスケードレイヤーとは、大規模なプロジェクトでCSSを記述する際にデベロッパーがより管理しやすくするためのCSSの新機能です。仕様の作成者であるMiriam Suzanne氏によると、カスケードレイヤーの機能は以下の通りです。

カスケードレイヤーは、詳細度のヒューリスティックやソースの順番に完全に依存することなく、内部のカスケードロジックを管理できるようにします。

前述の例にカスケードレイヤーを適用してみましょう。
最初にレイヤーを定義します。 @の後にレイヤー名を記述するだけです。

componentsというレイヤーを定義しました。そのレイヤーの中に、デフォルトのボタンスタイルを記述します。

次に、バリエーション用のレイヤーを用意し、同様にスタイルを記述します。

下記はレイヤーの概念を視覚化したものです。
CSSでは最後に定義されたものがレイヤーリストの最初になるので、Photoshopのレイヤーと似ています。

レイヤーの概念

レイヤーの概念

この例では、variationレイヤーが最後に定義されているので、componentsレイヤーよりも優先(オーバーライド)されます。

また、どのレイヤーを優先するかは記述の順番だけでなく、最初に優先度を定義する方法もあります。

前述の例に戻ります。
最初の問題は、ボタンの別のバリエーションを作成する必要がありましたが、バリエーションボタンの詳細度が低くなる場所に記述してしまったことです。カスケードレイヤーを使用すると、variationsレイヤーにCSSを記述することができます。

これで、ベースのスタイルよりもコンポーネントのバリエーションが常に優先されるようにすることができます。

上記の説明を視覚的に見てみましょう。
レイヤーパネルで、各ボタンがどのようにレイヤー内で機能するかに注目してください。順番は上部にある@layerの定義に従っています。

レイヤーの概念

レイヤーの概念: ブルーになる

上部の@layerで順番を変更すると、componentsレイヤーがvariationsより優先されます。その結果、デフォルトのボタンスタイルにオーバーライドされます。

レイヤーの順番を変更

@layerでレイヤーの順番を変更: デフォルトのレッドになる

レイヤーにスタイルルールを追加する

カスケードレイヤーでは、ブラウザは同じ@layer定義のスタイルを組み合わせて、その順番に従って一度に読み込みます。

上記のCSSの場合、ブラウザはvariationsレイヤーの.button--ghostの直後に.button--facebookを追加することになります。
下記は、この概念を視覚化したものです。

レイヤーの概念

レイヤーの概念

サポートブラウザ

サポートしているブラウザは、CSSの新機能を考える上で最も重要な問題です。この記事の執筆時点で、Firefox、Chrome、Safari TPでサポートされています。

【訳者注】2月にリリースされたFirefox 97ではデフォルトでサポートされ、3/1にリリースされたChrome 99でもサポートされました。Safariは次期バージョンでサポートされる予定です。
参考: Firefox, Chrome, Safari

カスケードレイヤーのサポートブラウザ

カスケードレイヤーのサポートブラウザ
※3/2のキャプチャですが、Chromeはまだ反映されていないようです。

拡張機能として使用できますか?
いいえ、できません。JavaScriptのポリフィルを使用しない限り(まだないです)。

レイヤーはカスケードのどこにありますか?

その疑問に答えるために、CSSカスケードの概要を見てみましょう。

CSS Cascadeは、以下のように順序付けられます(高いものほど優先されます)。

  • Origin and Importance(宣言の出自と!important
  • Inline Styles(インラインスタイル)
  • Layer(レイヤー)
  • Specificity(詳細度)
  • Order of appearance(記述の順番)

下記の図は線が太く濃いほど、そのスタイルがカスケードでより優先されることを意味します。

CSSカスケードの概要

CSSカスケードの概要

Origin and Importance(宣言の出自と!important

スタイルルールの出自と重要性は異なるもの(しかし関連しています)なので、それぞれについて解説します。

スタイル ルールのOrigin(出自)は優先順位の高い順に、以下のいずれかになります。

  • デベロッパーによるスタイル
  • ユーザーによるスタイル
  • ブラウザによるスタイル

つまり、デベロッパーが作成したCSSは、常にユーザーとブラウザのスタイルに優先されます。

例を見てみましょう。

ユーザーがブラウザのデフォルトのフォントサイズを変更しようとした場合、上記のCSSはユーザーの設定をオーバーライドします(デベロッパーのスタイルがユーザーのスタイルに勝つため)。

ユーザーの設定

ユーザーの設定したスタイルをオーバーライドする

これはアクセシビリティにとって悪い使用例です。実際のプロジェクトでは行わないでください。スタイルの出自を説明するために提示したものです。

ブラウザのスタイルとは、UAスタイルシートです。たとえば、<button>のデフォルトのスタイルは各ブラウザごとに異なります。そしてデベロッパーのスタイルがブラウザのスタイルに勝つため、デフォルトのスタイルをオーバーライドすることができます。

<button>をデベロッパーツールで調べると、UAスタイルシートによりデフォルトのスタイルが適用されていることが分かります。

デベロッパーツールのキャプチャ

<button>のスタイルを調べる

上記はすべて通常のルールです。つまり、!importantというキーワードがないという意味です。もしある場合は、次のような順番になります。

  • ブラウザによるスタイル(!importantあり)
  • ユーザーによるスタイル(!importantあり)
  • デベロッパーによるスタイル(!importantあり)
  • デベロッパーによるスタイル(通常)
  • ユーザーによるスタイル(通常)
  • ブラウザによるスタイル(通常)

Inline Styles(インラインスタイル)

要素にインラインスタイルがある場、同じ重要度を持つ兄弟の中で最も高い詳細度を持つことになります。

下記のHTMLとCSSはインラインスタイルが優先されるため、<button>のカラーは#fffになります。

Layer(レイヤー)

そして、レイヤーです!
これはカスケードの新しいお客さまです。カスケードレイヤーは、セレクタの詳細度よりも優先されます。下記の例で、カスタムレイヤーのp要素のフォントサイズはどうなると思いますか?

フォントサイズは2remです。カスケードレイヤーでは要素の詳細度に関係なく、次のレイヤでオーバーライドされる場合は無視されます。

Specificity(詳細度)

レイヤーの後にブラウザはCSSのルールを確認し、セレクタの詳細度に基づいてどちらが勝つか判断します。

下記は簡単な例です。
.newsletter .buttonは、.buttonよりも高い詳細度を持っています。その結果、.buttonのスタイルは.newsletter .buttonのスタイルにオーバーライドされます。

Order of appearance(記述の順番)

最後に、記述の順番が実行されます。2つの要素の詳細度が同じ場合、CSSドキュメント内での順番によって、どちらが勝つかが決まります。

上記のルールはどちらも同じ詳細度です。しかし、.newsletter .buttonの方が後に記述されているので、勝ちます。

レイヤーがカスケードの中でどのような位置づけにあるのかがわかったところで、カスケードレイヤーの使用例を見てましょう。

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

カスケードレイヤーが実際のプロジェクトで輝ける場所はどこだろうと考えてみたところ、次の用途を思いつきました。

UIテーマの切り替え

私が取り組んでいるプロジェクトでは、UIテーマの設定にカスケードレイヤーを使用することが完璧なソリューションになります。ここで解決される問題は、デベロッパーである私がCSSを変更することなくテーマを切り替えられるようになること、あるいは何らかの方法で並び替えができるようになることです。

CSSにはさまざまなレイヤーがあり、最後にthemesレイヤーがあります。そして、themesレイヤーには複数のレイヤーを入れ子にすることができます(カスケードレイヤーはネストをサポートしています)。

themesレイヤー内で最初に@layer custom, defaultを定義していることに注目してください。これでdefaultcustomをオーバーライドします。

UIテーマを切り替えたい時は、@layer themes内の最初の定義でレイヤーを並べ替えだけです。

サードパーティのCSS

カスケードレイヤーは、サードパーティのCSSにも便利です。たとえば、flickityのカルーセルを例に見てましょう。!importantがたくさん使用されています。

カスケードレイヤーを使用すると、コンポーネントレイヤーの前にサードパーティーのCSSを追加することができます。外部CSSファイルをインポートして、レイヤーに割り当てることができます。

詳細度の問題を心配する必要がなくなる

リストのコンポーネントがあり、リストのマージンが小さいバリエーションが必要だとします。

:not疑似セレクタは要素の詳細度を高くするため、:notを再利用しないとオーバーライドできません。

上記のCSSでは.list__item--compactは、.list__itemをオーバーライドしません。.list__itemには:notがあり、詳細度が高いためです。これを機能させるには、下記のように記述しなければなりません。

この問題をカスケードレイヤーで解決してみましょう。
@layer listレイヤーにbaseoverridesを入れ子にします。overridesにはバリエーションのスタイルを記述し、overridesが後に記述されているので期待通りに動作します。

ネストされたコンポーネント

メインのソーシャルフィードアイテムに対するアクション(いいね、コメント)のリストと、各コメントごとに別のリストがあります。

ネストされたコンポーネント

ネストされたコンポーネント

アイコンのサイズはフィードでは24pxで、コメントではサイズが小さくなります。

.feed-item .c-iconが、.comment__iconよりも詳細度が高いことに注目してください。これはカスケードレイヤーを使用する利点です。

ユーティリティCSS

ユーティリティのCSSクラスには、常に要素に適用されるように!importantを付けることに慣れてきたかもしれません。しかし、カスケードレイヤーを使用すれば、ユーティリティを最後に配置することができます。

たとえば、ユーティリティクラス.px-0を持つヘッダがあり、このクラスでパディングの左右を0にリセットしたいとします。

カスケードレイヤーを使用すれば、詳細度を気にせず、!importantも付けずに記述できます。

カスケードレイヤーについてさらに詳しく

レイヤー化されていないスタイルは詳細度がより高い

レイヤー化されていないCSSのスタイルがある場合、暗黙的に最後のレイヤーに追加されます。

上記のCSSでは、.buttonルールが@layerなしで定義されており、ブラウザにとってこの.buttonルールは暗黙的にレイヤーに配置されることになります。

終わりに

カスケードレイヤーはCSSのエキサイティングな機能です! この記事で見たように、かなり便利に使うことができます。私にとっての唯一の制約は、CSSだけでは拡張機能として使用できないことです。そのため、Webコミュニティでレイヤーの採用は少し遅れるかもしれません。

関連リソース

この記事があなたのお役に立てれば幸いです。
コメントや提案があれば、@shadeed9までお願いします。

sponsors

top of page

©2022 coliss