CSSの新機能@scopeが便利すぎる! セレクタの適用範囲を設定できる、@scopeの基礎知識と使い方
Post on:2023年8月30日
CSSでこの機能を待ち望んでいた人もいると思います。
セレクタの適用範囲を設定できる@scope
がいよいよChromeでサポートされます。@scope
の基礎知識と使い方を紹介します。
たとえば、下記のHTMLにはimg
が2つあります。@scope
を使用すると、1つ目の.media-object
直下のimg
にのみスタイルを適用できます。.content
内のimg
はターゲットにされません。
A quick introduction to CSS @scope
by Bramus!
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
CSSの@scope
についてご存じですか?
@scope
はセレクタの範囲を設定するCSSの新しい機能で、中間要素に名前を付ける必要がなくなるため、BEMなどによる命名規則から離れることができます。
10月頭にリリース予定のChrome 118で実装される予定なので、@scope
の使い方を見てましょう。
CSS @scopeがなぜ必要なのか
@scope
がなぜ必要なのかその理由を示すことから始めます。
まずは、デモページをご覧ください。
See the Pen
✅ CSS Scoped Styles 1/4: Problem Statement by coliss (@coliss)
on CodePen.
デモのHTMLは、下記の通りです。
親に.light
が設定されておりテキストリンクがあり、子に.dark
とテキストリンクがあり、孫に.light
とテキストリンクがあります。
1 2 3 4 5 6 7 8 9 |
<div class="light"> <p><a href="…">What color am I?</a></p> <div class="dark"> <p><a href="…">What about me?</a></p> <div class="light"> <p><a href="…">Am I the same as the first?</p> </div> </div> </div> |
CSSは下記の通りです。
1 2 3 4 |
.light { background: #ccc; } .dark { background: #333; } .light a { color: red; } .dark a { color: yellow; } |
孫の3番目のテキストリンクのカラーに注目です。
デモをブラウザで表示すると、孫には.light a { color: red; }
と設定されていますが、レッドではなく、イエローで表示されてしまいます。
Chrome 116でキャプチャ
CSSカスケードの仕組み
イエローに表示されてしまうのは、CSSカスケードの仕組みによるものです。
使用されているセレクタは同じ詳細度を持つため、カスケードは「出現の順番(Order of Appearance」に進みます。そのため、.dark a
が最終的に適用されます。そして、色は継承されるため、その入れ子になった.light
内のテキストリンクもイエローになります。
CSSカスケードの仕組み
CSS @scopeの基本的な使い方
CSSの@scope
を使用するとこの問題を簡単に解決できます。
CSSのスタイルルールのスコープに使用し、スコープルート(scope root)と各スタイルルール間にスコープの近接を適用します。
スコープルートは@scope
の括弧で囲まれた部分です。下記のCSSはで.light
と.dark
です。
1 2 3 4 5 6 7 8 9 |
@scope (.light) { :scope { background: #ccc; } a { color: red;} } @scope (.dark) { :scope { background: #333; } a { color: yellow; } } |
これが機能する理由は、スコープがカスケード内でステップ(Scope Proximity)を追加するからです。同じ詳細度の宣言は、ソースの順番に戻る前にスコープルートへの近接度によって重み付けされます。
クールだと思いませんか!🤩
CSSカスケードの仕組み
@scope
を使用してデモを表示すると、.ligth
は親も孫もレッドになり、.dark
はイエローになります。これはもっとも近いスコープのルートを検索するからです。
Chrome Canary 118でキャプチャ
@scopeのさらに優れた使い方
@scope
のさらに優れた点は、スコープの終点を設定して「ドーナツスコープ(donut scope)」を作成できることです。
1 2 3 |
@scope (.media-object) to (.content) { img {...} } |
@scope
ブロック内のセレクタは、スコープの始点と終点の間の要素のみを対象とします。上記のCSSの場合、始点は.media-object
で、終点は.content
になります。
以下のHTMLと組み合わせると、CSSは.content
内のimg
はターゲットにされません。
1 2 3 4 5 6 |
<div class="media-object"> <img> <div class="content"> <img> </div> </div> |
これにより、ヘッダ画像に.media-object__header__image
などの名前をつけていたBEMや複雑なセレクタを使用する手法から離れることができます。
@scope
を使用すると、そういった必要はなくなり、スコープの終点を使用してセレクタの範囲を切り離すだけです。
一つ重要な注意点があります。@scope
はセレクタの範囲を制限するものであり、継承を止めたり防いだりするものではないということです。
たとえば、ドーナツスコープ内のカラー宣言は、スコープの外側にあるツリーの奥の子にも継承されます。
CSSの@scope
はChrome 118から実装予定で、10月に安定版がリリースされます。また、Chrome Canaryではすでに実装されています。
sponsors