グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



CSSの新機能「カスケードレイヤー」を使ってもっと簡単にスタイルを管理しよう

web制作の現場においてCSSでのスタイリングは欠かせないものですが、意図した装飾とならずに困った経験がある人は多いのではないでしょうか?

CSSのスタイリングを適用する際には、詳細度や記述の順番を考えてコーディングを行う必要がありますが、新しい機能として「カスケードレイヤー」が利用可能になりました。
今までとは違った管理が可能になるおもしろい機能なので使い方をご紹介したいと思います。

CSSの新機能、カスケードレイヤー とは

カスケードレイヤーとはその名の通り「カスケード(優先順位)」を「レイヤー(階層)」で管理することができる機能で、今までのCSSには無い新しい概念でスタイルを指定することができるようになります。

本記事執筆時点(2022年9月7日)では全てのモダンブラウザで利用可能となっています。

IE11のサポートがなくなったことで利用できるようになった機能の1つですね。

詳細度のおさらい

カスケードレイヤーの使い方の前に、CSSセレクタの詳細度について簡単におさらいしてみます。

CSSセレクタの詳細度はスタイルの適用に関する優先度を管理するためのもので、より具体的に、より詳細に指定されたセレクタのスタイルが優先して適用されます。

※下記以外にもブラウザのデフォルト指定や、ユーザーが個別に設定する指定もありますが、本記事ではweb制作者が指定可能なものに限定して説明します。

【↑ 詳細度高】

1. !important
2. style属性(インライン指定)
3. IDセレクタ
4. クラスセレクタ・属性セレクタ・擬似クラス
5. 要素セレクタ
6. ユニバーサルセレクタ

【↓ 詳細度低】

「!important」による指定、「sytle属性」による指定は上書きが難しいため、一般的には「IDセレクタ」「クラスセレクタ・属性セレクタ・擬似クラス」「要素セレクタ」の3つを利用して詳細度の管理を行うことが多くなります。

この3つのセレクタは点数をつけて計算されることが多く、下記のようなルールで採点します。

セレクタの種類 点数
IDセレクタ 1.0.0
クラスセレクタ・属性セレクタ・擬似クラス 0.1.0
要素セレクタ 0.0.1

実際のセレクタで確認してみると

/* IDセレクタが2つ、クラスセレクタが1つ、要素セレクタが0なのでなので、2.1.0 */
#home #main .button {}

/* IDセレクタが1つ、クラスセレクタが2つ、要素セレクタが0なので、1.2.0 */
#main .section .button {}

/* IDセレクタが1つ、クラスセレクタが2つ、要素セレクタが1つなので、1.2.1 */
#home .section a.button {}

上記のような点数で計算されます。 点数はセレクタの種類ごとに計算され、左側の桁の数値が大きくなるセレクタほど詳細度が高くなり、スタイルの適用が優先される形になります。 上記例では、一番上の例が最も優先されるセレクタです。

また、どれだけセレクタの数が多くても、2進数や10進数のようにケタ上がりすることはなく、上位のセレクタより詳細度が高くなることはありません。

/* 1.0.1 */
/* こっちのセレクタの勝ち! */
#main a {}

/* 0.6.1 */
.hoge .fuga .moge .piyo .foo .bar a {}

上記の場合は、クラスセレクタが6つありますが、IDセレクタ1つの方が詳細度が高いセレクタとして適用されることになります。

詳細度を視覚的に計算できるサービス等もありますので、コーディング中に迷ったら確認するようにすると色々と捗ります。

カスケードレイヤーの使い方

カスケードレイヤーは、先述したCSSセレクタの詳細度に加えて、「レイヤー」という別の手法を利用して管理するための新しい機能になります。

文法は

@layer default {
    .hoge {
        font-size: 2rem;
    }
}

のように @layer に識別子を指定する形式で記述します。レスポンシブコーディングの時によく使うメディアクエリーに似た書き方ですね。

レイヤー内に記述されたセレクタは1つの階層(グループ)としてまとめられ、指定した階層(グループ)ごとにスタイルの優先順位を管理できるようになります。

レイヤーの優先順位を指定しないスタイルの適用

<style>
@layer default {
    .button {
        color: red;
    }
    .link {
        color: red;
    }
}

@layer custom {
    .button {
        color: blue;
    }
    .link {
        color: black;
    }
}
</style>

<!-- これは青い文字のボタンです -->
<button class="button">ボタンをクリック</button>

<!-- これは黒い文字のリンクです -->
<a class="link">リンクをクリック</a>

上記の場合は、 default レイヤーと custom レイヤーの2つのグループが作成されますが、このままでは記述した順番でスタイルが適用されるだけで今までのCSS管理と差はありません。

記述した順番で button 要素と a 要素にスタイルが適用されました。

レイヤーの優先順位を指定したスタイルの適用

/* この1行を追加 */
@layer custom, default;

@layer default {
    .button {
        color: red;
    }
    .link {
        color: red;
    }
}

@layer custom {
    .button {
        color: blue;
    }
    .link {
        color: black;
    }
}

<!-- 赤い文字のボタンになりました -->
<button class="button">ボタンをクリック</button>

<!-- 赤い文字のリンクになりました -->
<a class="link">リンクをクリック</a>

先ほどと同じレイヤー、セレクタ、スタイルを指定していますが、1行目に追記した

@layer custom, default;

の部分で、レイヤー単位の優先順位を指定しています。(通常のCSS同様、後に記述したものが優先されます)

この指定により、CSSセレクタとレイヤーの記述順序はそのままにスタイルを適用する優先順位を変更することができました。

レイヤーと詳細度の関係

先ほどの例では同じ詳細度のセレクタの指定でしたので記述順序に関する管理のみでしたが、詳細度の異なるセレクタが組み合わさるとより便利に利用できます。

<style>
@layer default, custom;

@layer default {
    #home #post #main .button {
        color: red;
    }

    #home #post #main .link {
        color: red;
    }
}

@layer custom {
    .button {
        color: blue;
    }
    .link {
        color: black;
    }
}
</style>

<div id="home">
    <div id="post">
        <div id="main">
            <!-- これは青い文字のボタンです -->
            <button class="button">ボタンをクリック</button>

            <!-- これは黒い文字のリンクです -->
            <a class="link">リンクをクリック</a>
        </div>
    </div>
</div>

最初の例と同じく、 custom レイヤーのスタイルが適用されました。

通常のCSSセレクタの詳細度のルールであればIDを複数組み合わせたセレクタが優先されるところですが、カスタムレイヤーを利用することでセレクタの詳細度よりも優先して、指定したレイヤーの順番にスタイルが適用されるようになりました。

従来であればより詳細度の高いセレクタを利用して上書きをする必要がありましたが、カスタムレイヤーを利用することでとても簡潔に管理できるようになります。

レイヤー化したセレクタとレイヤー化されていないセレクタ

レイヤー化されたセレクタ同士の比較は先度確認しましたが、既存のCSSのようなレイヤー化されていないセレクタと併用する場合はどうなるのでしょうか。

<style>
@layer default, custom;

@layer default {
    #home #post #main .button {
        color: red;
    }

    #home #post #main .link {
        color: red;
    }
}

@layer custom {
    .button {
        color: blue;
    }
    .link {
        color: black;
    }
}
/** レイヤー化していない従来のセレクタ **/
.button {
    color: orange;
}
.link {
    color: orange;
}
</style>

<div id="home">
    <div id="post">
        <div id="main">
            <!-- これはオレンジの文字のボタンです -->
            <button class="button">ボタンをクリック</button>

            <!-- これはオレンジの文字のリンクです -->
            <a class="link">リンクをクリック</a>
        </div>
    </div>
</div>

この場合はレイヤー化されていないセレクタのスタイルが最優先されるようです。様々な条件のCSSと組み合わせて使う場合の互換性を考えて、ということでしょうか。 既存のCSSをさらにレイヤー化することで回避するなどの管理方法がありますが、詳細はまた別の記事でお伝えできればと思います。

さいごに

CSSの新機能、カスケードレイヤーのご紹介でした。

CSSセレクタの詳細度の管理方法に関しては多くのweb制作者が悩まされている問題だと思います。「!importantはできるだけ使わない」や、「IDセレクタは2つ以上使わない」など、様々なルールでコーディングを行いますが、仕様や納期との兼ね合いでルールを守り切れないこともしばしば。

この手の問題は、詳細度を上げること自体が問題なのではなく、それにより後から修正する時に苦労することに他なりません。

カスケードレイヤーにより、セレクタの詳細度とは別のアプローチでスタイルを管理することで、CSSコーディングが少しでも楽しいものになればいいなと思う今日この頃です。

この記事を書いた人

なかもと
なかもとソリューション事業部 マークアップエンジニア
企画・営業部を経て、システムエンジニア、マークアップエンジニアとしてweb サイト制作、webアプリケーション開発の上流から下流まで幅広く携わる。ユーザビリティ、アクセシビリティを意識したセマンティックなマークアップとより良いユーザー体験を追及して日々奔走中。三度の飯よりwebが好き。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします