CSS Layersは2022年にすべてのモダンブラウザでサポートされた新機能で、CSSのカスケードを層(レイヤー)で管理できる画期的な仕組みです。しかし実際にプロジェクトで使ってみると、理想と現実の間にはいくつかの課題があることが分かりました。
CSS Layersとは何か
CSS Layersは @layer
ディレクティブを使って、CSSのスタイルを階層的に管理する仕組みです。従来の詳細度による優先順位ではなく、レイヤーの順序で明確にスタイルの適用順序を制御できます。
基本的な使い方
/* レイヤーの順序を定義(左から右へ優先度が上がる) */
@layer foundations, components, utilities;
/* 各レイヤーにスタイルを定義 */
@layer foundations {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
}
}
@layer components {
.button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
}
}
@layer utilities {
.text-center {
text-align: center;
}
}
サブレイヤーでより細かな制御
@layer foundations, components, utilities;
@layer components.bases, components.variations, components.states;
@layer components.basess {
.button {
padding: 0.5rem 1rem;
background: #007bff;
color: white;
}
}
@layer components.variations {
.button--large {
padding: 1rem 2rem;
font-size: 1.2rem;
}
}
@layer components.states {
.button:hover {
background: #0056b3;
}
}
CSS Layersの素晴らしい利点
1. 詳細度の悩みから解放
従来のCSS開発で最も頭を悩ませる詳細度の問題を根本的に解決できます。
/* 従来の問題 */
.header .nav .menu .item a { color: blue; }
/* さらに詳細度を上げて上書き... */
.header .nav .menu .item a.active { color: red; }
/* CSS Layersなら */
@layer foundations {
.nav-link { color: blue; }
}
@layer utilities {
.active { color: red; } /* シンプルなクラスでも確実に優先される */
}
2. 構造的なCSS管理
プロジェクトのCSS構造が明確になり、チーム開発での保守性が向上します。
@layer
foundations, /* 基本スタイル */
components, /* コンポーネント */
layouts, /* レイアウト別スタイル */
utilities; /* ユーティリティ */
3. !importantに頼らない開発
レイヤーの順序だけで優先順位が決まるため、!important
を乱用する必要がありません。
実際に使って分かった問題点
1. 最大の課題:プラグインCSSとの共存
CSS Layersの最も重要な仕様上の制限:
CSS Layersは、レイヤー化されていないCSS(通常のCSS)の方が、すべてのレイヤーよりも優先度が高くなるという致命的な欠陥を抱えています(書き方は同じなのに、CSSメディアクエリと同じように使えない)。
/* あなたの美しいレイヤー構造 */
@layer foundations, components, utilities;
@layer utilities {
.margin-0 { margin: 0; } /* 最高優先度のつもり... */
}
/* でも、プラグインの普通のCSS */
.some-plugin-class {
margin: 20px; /* こちらが勝ってしまう! */
}
これにより、WordPressプラグインやサードパーティライブラリのCSSが、あなたの精密に設計されたレイヤー構造を無視して最優先で適用されてしまいます。
2. 具体的な被害例
/* プラグインが定義する野蛮なリセット */
* {
margin: 0;
padding: 0;
box-sizing: content-box; /* あなたのborder-boxを上書き */
}
/* あなたのレイヤー内の設定は無力 */
@layer resets {
* { box-sizing: border-box; } /* 負ける */
}
@layer utilities {
.p-4 { padding: 1rem; } /* 負ける */
}
3. @importのパフォーマンス問題
CSS Layersは @import
と組み合わせて使うこと(もしくは、そう紹介されていること)が多いですが、@import
は直列読み込みのためパフォーマンスに悪影響があります。
/* パフォーマンスが悪い例 */
@import url('resets.css') layer(resets);
@import url('components.css') layer(components);
@import url('utilities.css') layer(utilities);
/* 3つのファイルを順番に読み込み = 遅い */
考えられる対処法
1. プラグインCSSを制御する
<?php
//functions.php
function control_plugin_styles() {
//問題のあるプラグインCSSを無効化
wp_dequeue_style('problematic-plugin');
//自分でレイヤー化した版を読み込み
wp_enqueue_style('plugin-layered',
get_template_directory_uri() . '/css/plugin-layered.css');
}
add_action('wp_enqueue_scripts', 'control_plugin_styles', 999);
?>
→ すべてのプラグインCSSを特定・指定する必要があり、工数的にまったく割りが合わない
2. 重要なユーティリティは非レイヤーで
@layer foundations, components;
/* utilities レイヤーは作らない */
/* 重要なユーティリティは普通のCSSとして定義 */
.text-center { text-align: center; }
.hidden { display: none; }
.margin-0 { margin: 0; }
/* これでプラグインCSSと同等の優先度 */
→ 部分的に使わないなら、そもそも @layer
を採用する意味がない
3. 戦略的な!important使用
@layer utilities {
.force-center {
text-align: center !important; /* プラグインに勝つ */
}
}
→ !important
を乱用しないための @layer
なのに本末転倒
実用的なレイヤー設計パターン
シンプルな構造
@layer
foundations, /* 基本なスタイル */
components, /* ボタン、カードなどのコンポーネントスタイル */
layouts, /* レイアウト別のスタイル */
utilities, /* 単一目的の調整用クラス */
trumps; /* それよりさらに上書きする緊急時の上書き用クラス(ITCSS) */
サブレイヤーを活用した構造
@layer foundations, components, utilities;
@layer foundations.settings, foundations.elements; /* foundations の変数設定, 要素スタイル */
@layer components.bases, components.variations; /* components の基本設定, バリエーション */
@layer foundations.settings {
:root {
--color-primary: #007bff;
--font-family: 'Arial', sans-serif;
}
}
@layer components.bases {
.button {
font-family: var(--font-family);
padding: 0.5rem 1rem;
}
}
@layer components.variations {
.button--primary {
background: var(--color-primary);
}
}
CSS Layersを使うべき?使わないべき?
使っても良いケース
- 新規プロジェクトで、サードパーティCSSを制御できる
- チーム開発で、CSS構造の統一が重要
- 大規模サイトで、CSS管理の複雑さに悩んでいる
- デザインシステムを構築している
使わない方が良いケース
- 既存のWordPressサイトで多数のプラグインを使用
- プラグインCSSを制御できない環境
- 小規模サイトで、そもそもCSS管理に問題がない
私の判断
今回のプロジェクトでは、プラグインの野蛮な * { margin: 0; padding: 0; }
がすべてを台無しにしてしまうため、CSS Layersの使用を断念しました。
現実的には、まだ多くのプロジェクトでCSS Layersを本格採用するには早すぎるかもしれません。特にWordPressなどのCMS環境では、プラグインエコシステムとの共存が大きな課題となります。
代替案:実用的なCSS管理手法
CSS Layersを使わない場合でも、以下の手法等で構造的なCSS管理は可能です:
1. ITCSS(Inverted Triangle CSS)
settings/ → グローバル変数、設定
generics/ → リセット、normalize 系などの広い設定
elements/ → HTML要素の基本スタイル
objects/ → 装飾のないデザインパターン
components/ → 具体的なUIコンポーネント
utilities/ → ヘルパークラス(!important を利用していい)
2. Dart Sass の @use / @forward
Dart Sassを使用している場合は、@use
と @forward
でモジュール化し、名前空間で管理できます。
// _variables.scss
$primary-color: #007bff;
$font-stack: Arial, sans-serif;
// _button.scss
@use 'variables' as *;
.button {
background: $primary-color;
font-family: $font-stack;
}
// main.scss
@use 'variables';
@use 'button';
@import
と異なり、@use
は:
- 変数のスコープが明確(グローバル汚染を防ぐ)
- 重複読み込みを自動で防ぐ
- パフォーマンスが良い
3. CSS-in-JSソリューション
React/Vue環境であれば、styled-componentsやEmotion等を使用してスコープ化されたスタイルを使うこともできます。
まとめ
CSS Layersは理論的には素晴らしい機能で、CSS管理の未来を感じさせます。しかし、現実のWeb開発においては以下の課題があります:
良い点
- 詳細度の問題を根本解決
- 構造的なCSS管理が可能
- チーム開発での保守性向上
課題
- プラグインCSSとの共存問題
- @importのパフォーマンス影響
- 学習コストと移行コスト
現段階では、新規プロジェクトで環境を完全にコントロールできる場合にのみ推奨します。WordPressなどの既存システムでは、従来のCSS管理手法の方が現実的かもしれません。