
ChatGPT のような AI がコードを書いてくれるようになってきた現在。Web 制作においてもこれからますます、フルスクラッチですべてをゼロから構築するのではなく、「便利なもの」を組み合わせ、調整して仕上げていくような制作プロセスが重要になっていくと考えられます。
ただし、いろいろなものを組み合わせると、出どころのさまざまな CSS が混在することになります。それぞれの適用順やセレクタの詳細度まで調整が必要になってくると、手間が大きくなり、組み合わせるメリットが半減してしまいます。
そんな問題を解決してくれるのが CSS のカスケードレイヤー @layer です。
そのため、今回の書籍『Astro v2とTinaCMSでシンプルに作るブログサイト』では、構築するブログサイトのスタイリングに @layer を取り入れています。
なぜカスケードレイヤー @layer を使うことにしたのか
@layer を取り入れたのは、「はがしやすいスタイル」にして、CSS が負の遺産となるのを防ぐためです。
まず、この書籍ではサイト構築の際に CSS を意識せず、Astro の機能に集中して作業できるようにするため、制作用のスタイルを用意することにしました。最初に適用してしまえば、サイトの基本的な見栄えやレイアウトが整うようにするスタイルです。

問題は、こうしたスタイルを用意すると、あとから便利な CSS フレームワークやライブラリを導入してサイトをブラッシュアップしていこうとしたときに、CSS が干渉して不和を引き起こす可能性があることです。
実際に、
- 手間のかかる記事本文のスタイリングには github-markdown-css や zenn-content-css を採用
- サイト完成後のカスタマイズには Tailwind CSS を導入
することを決めていました。けれども、これらの適用順やセレクタの詳細度は考えたくありません。さらに、制作用のスタイルはそのまま一緒に使用することも、不要な部分だけを取り去ることも簡単にできるのが理想です。
こうした要件を満たすため、制作用のスタイルは @layer でレイヤー化して管理することにしました。
たとえば、ベース部分とレイアウト部分でレイヤーを分けて管理しておけば、はがしやすい構成にできます。さらに、レイヤー化されていない CSS フレームワークやライブラリのスタイルは優先順位が最も高くなり、適用順や詳細度を意識する必要がなくなるためです。

カスケードレイヤー @layer とは
カスケードレイヤーは CSS のスタイルをレイヤー(階層)に分けて管理し、レイヤー単位で優先順位を設定できる機能です。レイヤーは @layer で作成します。
作成した順にレイヤーの優先順位が決まるため、一番最初に「@layer default, layout, theme」といった形ですべてのレイヤーを作成し、優先順位をコントロールするのがおすすめです。
ここでは default、layout、theme の3つのレイヤーを作成しています。最も優先順位が高くなるのは theme レイヤーです。
@layer default, layout, theme;
※「base」というレイヤー名を使用すると Tailwind CSS と併用したときにエラーとなるため、「defalut」を使用しています。
作成したレイヤーには、どこからでも「@layer レイヤー名 {...}」でスタイルを追加できます。
たとえば、下記のようにスタイルを追加すると、「@layer レイヤー名 {...}」がどのような順で適用されても、優先順位が高くなるのは theme レイヤーのスタイルです。そのため、ページの背景は黒色に、文字は白色になります。

@layer default { * { box-sizing: border-box; }
body { background: papayawhip; color: navy; }}
@layer layout { .flex { display: flex; }}
@layer theme { body { background: black; color: white; }}
コンポーネントごとに管理するスタイルも、@layer でレイヤーに追加してくことができます。import したスタイルや CSS in JS などのスタイルがどのような順で適用されるかはフレームワークによるところが大きいのですが、レイヤーを使えばそのあたりも気にしなくてよくなります。
レイヤー化されていないスタイルの扱い
レイヤー化されていないスタイル(unlayered style)は、@layer の策定段階では優先順位が最も低くなるとされていました。しかし、レイヤーがもたらす変化を考慮し、最終的には「レイヤー化されていないスタイル」を最上位とすることに決まりました。

body { background: orange;}
@layer theme { body { background: black; color: white; }}
最初にこれを知ったときは、正直なところがっかりしました。自前の CSS をレイヤー化すれば、それだけでライブラリの CSS を上書きできると考えていたためです。
もちろん、ライブラリの CSS も @import を使ってレイヤー化できるのですが、パフォーマンスの観点から @import での適用はあまり推奨されません。<link>で適用する方法については協議中です。
@import(library.css) layer(library-layer);
また、フレームワークのしくみの中では、@import で適用する形にするのが難しいケースもあります。
そのため、ライブラリの CSS の上書きを考えるのであれば、ライブラリの対応待ちというのが現状です。Tailwind CSS の場合、バージョン 4 でのカスケードレイヤーの導入が検討されているようです。
一方で、今回の書籍のように「はがしやすいスタイル」ということを考えるのであれば、十分に活用していけます。
レイヤーで !important を使うとどうなるのか
今回は実際に使うことはありませんでしたが、!important をつけたスタイルについてはレイヤーの優先順位が逆になります。
たとえば、次のようにするとレイヤー化されていないスタイルよりも、theme レイヤーのスタイルの方が強くなり、背景が黒くなります。

body { background: orange !important;}
@layer theme { body { background: black !important; color: white; }}
CSS フレームワークなどを使用せず、自前の CSS だけで構成する場合でも、レイヤー内でだけ詳細度を意識すればよくなるため、スタイルの管理が大幅に楽になると感じました。今後の制作・開発環境では欠かせない機能になっていくのではないでしょうか。
⬇️ カスケードレイヤー @layer を使用した書籍です

Astro v2とTinaCMSでシンプルに作るブログサイト
サクサク構築しながらAstroの基本機能を習得