🔥

CSSカスケード ~カスケードレイヤー~

に公開

前回の続き

カスケードレイヤーとは

カスケードレイヤーとは、CSSのスタイル適用順序をより細かく制御するために導入されたしくみのこと。

従来の問題として、複数のライブラリやコンポーネント、ユーティリティ CSS を併用するとき、どのルールが優先されるかが複雑になり、意図せずスタイルが上書きされたりすることがあった。

これを解決するためのしくみとしてカスケードレイヤーがある。

MDNのドキュメント

書き方

@layerでレイヤーを定義する。

/* レイヤー定義(順序がそのまま優先順位) */
@layer base, components, utilities;

/* 各レイヤーにスタイルを割り当て */
@layer base {
  html { font-size: 16px; }
  a { color: blue; }
}

@layer components {
  .btn { padding: 0.5em 1em; border-radius: 4px; }
}

@layer utilities {
  .text-center { text-align: center; }
}

入れ子にすることも可能。

@layer base, base.nested-components, base.nested-components2;

@layer base {
  @layer nested-components {
    html { font-size: 16px; }
    a { color: blue; }
  }
  @layer nested-components2 {
    .btn { padding: 0.5em 1em; border-radius: 4px; }
  }
}

メリット

  • 大きなプロジェクトで「共通ベース → コンポーネント → ユーティリティ」といったスタイル階層を明確化
  • 意図しない上書きが起こりにくく管理が楽に

活用方法

@importと組み合わせることで、外部ライブラリをベースとしてスタイリングすることが容易になる。

@layer external;
@import url('https://example.com/external-library.css') layer(external);

/* 自分のスタイルで上書き */
@layer custom, utilities;

@layer custom {
  /* 略 */
}

/* utilities レイヤーのスタイル */
@layer utilities {
  /* 略 */
}

@media@supportsなどと組み合わせることで、特定条件下のみにレイヤーを設定することができる。

/* ダークモードのときのみ適用 */
@media (prefers-color-scheme: dark) {
  @layer theme {
    body { background: #222; color: #eee; }
  }
}

細かい仕様

https://developer.mozilla.org/en-US/play でも実際に試してみると良い。

@layerは最上位に書かなくても良い

body { font-size: 16px }

/* ここで宣言しても有効 */
@layer base, components;

@layer base {
  /* 略 */
}

@layer components {
  /* 略 */
}

並べて宣言しなくても良い

/* 最上位に @layer base, components と書いたときと同じ優先順位 */
@layer base {
  /* 略 */
}

body { font-size: 16px }

@layer components {
  /* 略 */
}

匿名のレイヤーをつくることができる

/* 最後に書いたレイヤーが優先されるため、文字色はgreenになる */
@layer base {
  body { color: red; }
}

@layer { /* 匿名レイヤー */
  body { color: green;  }
}

再宣言することができる

/* 文字色がblueで下線が引かれた状態になる */
@layer base {
  body { color: red; text-decoration: underline; }
}

@layer base {
  body { color: blue; }
}

一度宣言したレイヤーの順番を並び替えることはできない

/* 文字色がgreen, 上線が引かれた状態になる */
@layer base {
  body { color: red; text-decoration: underline; }
}

@layer components {
  body { color: green; }
}

@layer base {
  body { color: blue; text-decoration: overline; }
}

/* 下のように書いたのと同じ 
@layer base {
  body { color: red; text-decoration: underline; }
  body { color: blue; text-decoration: overline; }
}

@layer components {
  body { color: green; }
}
*/

レイヤー外のスタイルが最優先で適用される

/* 文字色はblue, 上線が引かれた状態になる */
@layer base {
  body { color: red; }
}

body { color: blue; }

@layer {
  body { color: yellow; text-decoration: underline; }
}

@layer components {
  body { color: black; text-decoration: overline; }
}

@layer {
  body { color: green;  }
}

入れ子の状態でも似たような事象を確認できる。

/* 文字色はblue, 上線が引かれた状態になる */
@layer base {
  body { color: blue; }
  @layer nested-components {
    body { color: yellow; text-decoration: underline; }
  }
  @layer nested-components2 {
    body { color: black; text-decoration: overline; }
  }
}
GitHubで編集を提案

Discussion