Blazor の「CSS の分離」
先日、Blazor の 「CSS の分離」に関して、下記の記事を公開しました。
Blazor の 「CSS の分離」とは、すなわち、Foo.razor.css 内で定義したスタイル定義は、Foo.razor 内でレンダリングした要素にしか適用されない仕組みである、という話でしたね。そして ::deep という Blazor 特有の疑似セレクタを使用することで、以降のセレクタには「CSS の分離」機能を働かなくさせることができる、という話でした。
子コンテンツを描画するコンポーネントではどうなるのか?
シナリオ
さてここで、子コンテンツを持つコンポーネント、というのを考えてみます。例えば以下のように ChildContent パラメータを持つ Container という Razor コンポーネントを実装したとして、
<div class="container">
@this.ChildContent
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
この Container を以下のように使用するものとします。
@page "/"
<main>
<Container>
<h1>Home</h1>
</Container>
</main>
この Blazor アプリケーションを実行すると、CSS スコープ ID をいったん省いた描画結果は以下のようになります (この Blazor アプリを実行してブラウザで開き、ブラウザの開発者ツールの "要素" パネルで確認します)。
<main>
<div class="container">
<h1>Home</h1>
</div>
</main>
::deep は必要?
さてここで、Home.razor.css 内のスタイル定義にて、<h1>Home</h1> の文字色を赤くしたい、とした場合、どのようにセレクタを書けばよいでしょうか?
<h1>Home</h1> は <Container>~</Container> の中に書かれているので、以下のように ::deep が必要になるのでしょうか?
::deep h1 { color: red; } /* ::deep は要る? 要らない? */
描画結果の CSS スコープ ID を確認する
改めて、今度は、CSS スコープ ID を含めて、描画された結果を確認してみます。
<main b-hdk3d1ivml>
<div class="container" b-16twpovmak>
<h1 b-hdk3d1ivml>Home</h1>
</div>
</main>
細かくて少し読みにくいのですが、よく見ると、Home.razor 内でマークアップした main 要素に b-hdk3d1ivml という属性が付いていますので、Home.razor の CSS スコープ ID は b-hdk3d1ivml であることがわかります。
同じように Container.razor 内でマークアップした div class="container" 要素には、b-16twpovmak という属性が付いていますから、Container.razor の CSS スコープ ID は b-16twpovmak であることがわかります。
このように、Home.razor および Container.razor それぞれの CSS スコープ ID がわかったとことで、<h1>Home<h1> 要素には、どちらのスコープ ID が付いているのかよく見てみると...
...
<h1 b-hdk3d1ivml>Home</h1>
...
付けられている属性値は b-hdk3d1ivml、すなわち、Home.razor の CSS スコープ ID でした。なので、Home.razor.css では ::deep 不要で以下のように指定すれば OK です。
h1 { color: red; }
まとめ
他のコンテナコンポーネントの子コンテンツ内にマークアップした要素については、そのコンテナコンポーネントの "領域" にあるように見えるため、なんとなく ::deep が必要そうに思われてしまいます。しかし実際には、CSS スコープ ID は、そういう "境界" で区切られるというよりは、「どのコンポーネントがその要素の描画を担当するか」で決まります。今回の例では、<h1>Home</h1> 要素を描画するのは Home.razor ということになります。Home.razor が、その <h1>Home</h1> 要素の描画位置とタイミングを Container.razo に "移譲" しているだけなのですね。
それがわかってしまえば、::deep を付けるべきかどうか、判断と理解がしやすくなることでしょう。