CSSの適用範囲を限定する@scopeについて
@scopeとは
CSSの@scopeは、CSSの適用範囲を指定するためのルールです。
例えば、下のコードのように@scope
を使ってスタイルを指定すると、main
要素内のdiv
要素にだけスタイルが適用されます。
@scope (main) {
div {
background-color: red;
}
}
ちょうど下の画像のように、@scope
の中で指定した要素の範囲内だけにスタイルが適用されるイメージですね!
実際にコードの実行結果をChromeブラウザーで確認してみましょう👇
main要素内の要素にだけスタイルが適用されていることがわかりますね!
さらに@scope
ルールの中で:scope
セレクターを指定することで、@scope
ルールの中の一番親である要素に対してCSSを指定することができます。
例えば以下の例では@scope
の親はmain
要素なので、:scopeを使うことでmain
要素に対してスタイルを指定することができますね!
ブラウザーのサポート状況
ちなみに今回の記事で取り上げる@scope
ですが、
2023年11月現在まだChromeやEdgeなどのブラウザーでしかサポートされていません。
今のところ、各ブラウザーでサポートされるまでは使用を控えた方が良いでしょう。
それを踏まえて残りの記事を読んでいただけると幸いです。
@scopeの魅力
@scopeの魅力としてCSSの適用範囲をto
を使ってさらに細かく指定できることが挙げられます。
例えば以下のようなHTMLがあったとします。
<main>
<section class="section1">
<h2>section1</h2>
<section class="section2">
<h2>section2</h2>
</section>
</section>
</main>
この時、section1
内のh2
だけにスタイルを適用したい場合、@scope
を使って以下のように指定できます。
@scope (.section1) to (.section2) {
h2 {
color: red;
}
}
このようにto
を使うと.section1
要素の中の.section2
までの間の要素にだけスタイルが適用されます。
.section2
の中の要素にはスタイルが適用されないから注意してね!
実際にChromeブラウザーで結果を見てみましょう。
.section2の中のh2にはスタイルが適用されていないことがわかりますね。
これを@scope
を使わずに書くと以下のようになります。
.section1 h2 {
color: red;
}
/* .section2 h2のスタイルはリセットする必要がある */
.section2 h2 {
color: black;
}
今までのCSSでもできなくはないのですが、
このように、スタイルを.section2 h2
ではリセットする必要があります。
今までの方法だと、.section1の中の.section2までの間の要素にだけスタイルを適用するのはかなり面倒ですよね。
CSS Nestingとの違い
@scope
に似たような機能として、今後各ブラウザーに実装される予定のCSS Nestingという機能もあります!
これはSassのようにネストしたCSSを書くことができるようになる機能です。
main {
section {
h2 {
color: red;
}
}
}
これは以下のようなCSSを書いたのと同じ意味になります。
main section h2 {
color: red;
}
@scopeと同じように決められた要素の中だけにスタイルを適用できるという意味では似ていますね!
では、CSS Nestingと@scopeの違いは何でしょうか?
スコープの範囲を指定できる
やはり先ほど紹介したようにスコープの範囲をto
を使って指定できることが大きな違いです。
CSS NestingだけではネストしたCSSを書くことができるだけで、スコープの範囲を指定することはできません。
すなわち、CSSの構造化にはCSS Nesting
を、CSSの適用範囲を指定するには@scope
を使うという使い分けが良いでしょう。
距離の近さで優先度を決定できる
さらに@scope
ではスコープ同士でのCSSの優先度の決定方法に決まりがあります。
それは、スコープの距離が近いほど優先度が高くなるというものです。
以下のHTMLを考えます。
<body>
<main>
<h2>タイトル</h2>
</main>
</body>
二つのCSSをみてみましょう。
@scope (main) {
h2 {
color: red;
}
}
@scope (body) {
h2 {
color: blue;
}
}
この時、main
の中にあるh2
は何色になるでしょうか?
答えはred
です。
これはmain
の中にあるh2
はmain
からの距離が1で、body
からの距離が2だからです。
@scope
により近い距離にあるスコープのCSSが優先されるということですね。
つまり@scope
はCSS Nestingだけでは実現できない、スコープの距離によっても優先度を決定できます。
似たような機能ですが、違いを理解してより効率的にCSSを書いていきましょう。
CSS Nestingと@scopeは互いに併用できる
先ほどはCSS Nestingと@scopeの違いについて説明しましたが、
CSS Nestingと@scopeはどちらか一方を選ばないといけないわけではありません。
以下のように互いに併用することもできます。
@scope (.card) to (header) {
:scope {
inline-size: 40ch;
aspect-ratio: 3/4;
> header {
border-block-end: 1px solid white;
}
}
}
このように、@scope
でCSSの適用範囲を絞りつつ、CSS NestingでCSSを簡潔に書くこともできます。
@scope
もCSS NestingもCSSをわかりやすく書く素晴らしい機能です!
早く全てのブラウザーでこれらの機能がサポートされることを筆者は願っています!
Authored by
Godai@steelydylan
Webサービスを作るのが好きなWebエンジニア。子供が産まれたことをきっかけに独立し法人化。サービス開発が大好き。
好きな言語はTypeScript。