tanaka101

身につくスキル

  • -グローバルCSSの役割とコンポーネントCSSとの違いを理解する
  • -CSS変数・カスケード・@layer の仕組みを説明できる
  • -CSS変数を使ったダークモード対応の仕組みを読み解ける
  • -clamp() を使ったレスポンシブデザインを書ける
進捗: 0 / 8

@layer で整理する

CSSの読み込み順による上書き問題を @layer で解決する方法を学びます。

CSSが増えると「順番」が問題になる

ここまでのレッスンで、グローバルCSSに書く内容を学んできました。

globals.css
/* 1. CSSリセット */
*, *::before, *::after { box-sizing: border-box; margin: 0; }
 
/* 2. ベーススタイル */
body { font-family: system-ui, sans-serif; line-height: 1.6; }
 
/* 3. デザイントークン(CSS変数) */
:root { --background: #ffffff; --text: #171717; }
 
/* 4. ダークモードの色定義 */
.dark { --background: #171717; --text: #ffffff; }
 
/* 5. レスポンシブなサイズ定義 */
h1 { font-size: clamp(1.5rem, 1.25rem + 1vw, 1.875rem); }

1つのファイルに書いているうちは問題ありません。
しかし、プロジェクトが大きくなると、CSSは複数のファイルに分ける必要があるでしょう。

styles/
├── reset.css         ← CSSリセット
├── base.css          ← ベーススタイル
├── components.css    ← ボタンやカードのスタイル
└── utilities.css     ← ユーティリティクラス

ここで思い出してほしいのが、レッスン2で学んだカスケードの「出現順」ルールです。

同じ詳細度なら、後に書いた方が勝つ。

つまり、CSSファイルの読み込み順がそのまま優先順位になります。

読み込み順を間違えるとどうなる?

次の例を見てください。2つのCSSファイルがあるとします。

  • base.css — ボタン全体のスタイル(button
  • theme.css — テーマ用のボタンスタイル(button で色を変更)
正しい順番: base.css → theme.css

ボタンは緑色になっています。theme.css が後に読み込まれたので、同じ button 同士で「出現順」ルールが適用され、緑色が勝ちました。

では、読み込み順を逆にしたらどうなるでしょうか?

逆の順番: theme.css → base.css

テーマの緑色が、ベースの青色に上書きされてしまいました。どちらも同じ button (同じ詳細度)なので、後に書いた方が勝つという出現順ルールがそのまま効いてしまうのです。

ファイルが2つならまだ管理できます。しかし、ファイルや等が10個、20個...と増えたとき、すべての読み込み順を正しく保つのは困難です。

@layer で「層」を作る

この問題を解決するのが @layer です。

@layer は、CSSにレイヤー(層)を作って、優先順位を明示的に宣言する仕組みです。

先ほどの base.csstheme.css の問題を解決してみましょう。

まず、レイヤーの優先順位を宣言します。

globals.css
/* base → theme の順に優先度が上がる */
@layer base, theme;

各レイヤーにスタイルを配置するには、@layer レイヤー名 { ... } と書きます。

globals.css
@layer base, theme;
 
@layer base {
  button {
    padding: 8px 16px;
    background-color: blue;
    color: white;
    border: none;
    cursor: pointer;
  }
}
 
@layer theme {
  button {
    background-color: green;
  }
}

こう書くと、ファイル内でどこに書いてもtheme レイヤーは base レイヤーより優先されます。

実際に確認してみましょう。あえて theme を先に、base を後に書いています。

@layer: 書く順番に関係なく優先順位が決まる

theme を先に、base を後に書いていますが、テーマの緑色がちゃんと反映されています。最初の @layer base, theme; の宣言で優先順位が決まっているからです。

レイヤーの優先順位

@layer の優先順位は、レッスン2 『カスケードと詳細度』 で学んだカスケードと同じ原則です。

後に宣言したレイヤーが優先される。

レイヤーは2つだけでなく、いくつでも作れます。実際のプロジェクトでは3層に分けるのが定番です。

globals.css
@layer base, components, utilities;
/*     ↑弱い                ↑強い    */
レイヤー優先度用途
base低いリセット、ベーススタイル
components中くらいボタン、カードなどのコンポーネント
utilities高い個別に上書きしたいユーティリティ

@layer の宣言がなく、どのレイヤーにも属さないスタイルは、すべてのレイヤーより優先されます。

globals.css
@layer base {
  p { color: blue; }
}
 
/* レイヤーに属さないスタイル → 最も強い */
p { color: red; }

この場合、p の文字色は赤になります。レイヤー外のスタイルが常に最優先されるためです。

複数ファイルでも安心

@layer の最大の利点は、ファイルが分かれていても優先順位が壊れないことです。

globals.css
/* 最初に優先順位を宣言 */
@layer base, components, utilities;
 
/* 各ファイルを読み込む(順番はもう気にしなくてよい) */
@import './reset.css' layer(base);
@import './components.css' layer(components);
@import './utilities.css' layer(utilities);

@import でファイルを読み込むとき、layer() を付けると、そのファイルのスタイルを指定のレイヤーに配置できます。

読み込み順を入れ替えても、レイヤーの宣言順で優先度が決まるため、スタイルが壊れることはありません。

次のステップ

@layer を使えば、「このファイルはこのファイルの前に読み込まないと壊れる」という暗黙の依存を明示的なルールに変えられます。

これで、グローバルCSSの主要な概念をすべて学びました。次のレッスンでは、コース全体を振り返り、学んだ知識を整理します。