零弐壱蜂

[CSS] カスケードレイヤー(@layer)とITCSSの概念を組み合わせた設計を考える

5 min read

カスケードレイヤーとは

CSS の Cascading に Layers という概念が追加された。

これまでのカスケードのソート順序は以下の判定基準に基づいてソートされていた(後述の方が優先される)。

  1. 出自と重要度(Origin and Importance)
  2. 文脈(Context)
  3. 要素に付されたスタイル(Element-Attached Styles)
  4. 詳細度(Specificity)
  5. 出現順序(Order of appearance)

Layers が追加されることで以下のような判定基準になる。

  1. 出自と重要度(Origin and Importance)
  2. 文脈(Context)
  3. 要素に付されたスタイル(Element-Attached Styles)
  4. 層(Layers)
  5. 詳細度(Specificity)
  6. 出現順序(Order of appearance)

https://www.w3.org/TR/css-cascade-5/#cascading

サンプルコード

カスケードレイヤーを利用すると詳細度や記述順などを気にせず書くことができる。

/* layerの優先度順を定義する */
@layer first, second;

/* 
  secondのあとにfirstが書かれてあるが、冒頭のlayerの優先度の定義により
  .test は `display: block` が適用される
*/
@layer second {
  .test {
    display: block;
  }
}

@layer first {
  .test {
    display: none;
  }
}

事前にlayerの優先度順を定義した上で以下の構文でスタイルを定義していく。

@layer レイヤー名 {
  /* スタイル */
}
レガシー環境での対応状況

対応状況

2022 年 1 月現在、下記のブラウザのバージョンにおいてサポートされている。なお、それより古いバージョンでも設定によって有効にできるものもある。ただし、現状はモバイル端末のブラウザで利用できるものはないようだ。

  • Firefox: 97-
  • Chrome: 99-
  • Edge: 99-
  • Safari: 15.4-

参照: https://caniuse.com/css-cascade-layers

ITCSS のレイヤー

ITCSS で提唱されているレイヤーは以下の通り。

  1. Settings
  2. Tools
  3. Generic
  4. Base
  5. Objects
  6. Components
  7. Utilities

ITCSS のレイヤーをカスケードレイヤーに落とし込む

ITCSS のSettingsToolsに関しては、プリプロセッサ上で利用する変数の定義、mixin、CSS Custom Properties などを利用したものが主になる(CSS Custom Properties の定義などはSettingsなどに置いておくケースはあるだろう)。

ITCSS のレイヤーをカスケードレイヤーで表現すると以下のようになる。

@layer Generic, Base, Objects, Components, Utilities;

@layer Generic {
  * {
    box-sizing: border-box;
  }
}

@layer Base {
  ul {
    list-style: square outside;
  }
}

@layer Objects {
  .ui-list {
    margin: 0;
    padding: 0;
    list-style: none;
  }
}

@layer Components {
  .products-list {
    border-top: 1px solid #999;
  }
}

@layer Utilities {
  .one-half {
    width: 50%;
  }
}

読み込み順の定義

@layer Generic, Base, Objects, Components, Utilities;

Generic の詳細度が最も低く、Utilities の詳細度が最も高くなる。

下記のように@layerの定義の順番が一致しなくても、上記の定義順の詳細度になる。

/**
 * @layer Generic, Base, Objects, Components, Utilities;
 * となっているので、Utilitiesが先に書かれてあっても、Baseの方が詳細度が低い扱いになる
 */
@layer Utilities {
  .test {
    display: none;
  }
}

@layer Generic {
  .test {
    display: block;
  }
}

カスケードレイヤーと@importの組み合わせ

カスケードレイヤーを利用する際、CSSファイルに定義を続けて書いていくと見通しが悪くなる。

@layer Generic, Base, Objects, Components, Utilities;

@layer Generic {
  * {
    box-sizing: border-box;
  }
}

// ...定義が続く

カスケードレイヤーは@importにレイヤー名を指定して読み込むことができる。構文は以下の通り。

@import url('読み込むCSS') layer(レイヤー名);

そのまま@importを利用することは現代ではあまりないが、レイヤーを指定してimportする機能は用意されている。

PostCSS でのカスケードレイヤーの利用

そのままCSSを利用するわけではなくPostCSSなどのメタ言語を利用していると先述の@importを利用する機会はほとんどない。PostCSSであればライブラリであるpostcss-importを利用して、先述の@importと同様の構文でカスケードレイヤーを指定した状態で読み込むことができる。

@import '読み込むCSS' layer(レイヤー名);

参考