(15/30)みんなで学ぶBlazor:CSS isolation(隔離)

(15/30)みんなで学ぶBlazor:CSS isolation(隔離)

時々、特定のコンポーネントに個別のスタイルを設定したいことがあります。しかし、すべてのclassを`wwwroot/css/site.css`に書いたり、特定の要素のスタイルを変更すると、1つの変更がすべてのコンポーネントに影響を与える可能性があります。このようなグローバルな競合は避けなければなりませんが、どうすればよいでしょうか?

最終更新 2021/12/18 22:35
StrayaWorker
読了目安 2 分
カテゴリ
Blazor
テーマ
一緒に学ぶBlazorシリーズ
タグ
.NET C# ASP.NET Core Blazor

CSS isolation の紹介

異なるコンポーネントに個別のスタイルを設定したい場合がありますが、すべてのクラスを wwwroot/css/site.css に記述したり、特定の要素のスタイルを変更すると、1つの変更ですべてのコンポーネントに影響を与える可能性があります。このようなグローバルな競合は避ける必要がありますが、どうすればよいのでしょうか?

.NET 5 では CSS 分離(CSS isolation)が導入されました。コンポーネントごとに個別の CSS ファイルを作成し、命名規則は {コンポーネント名}.razor.css とします。このファイルは自動的に {コンポーネント名}.razor と結合され、大文字小文字は区別されません。以下の図のように、Blog.razor.css でも blog.razor.css でも Blog.razor と同じグループとして扱われます。

CSS 分離はビルド時に処理され、Blazor は CSS セレクターを書き換えて {プロジェクト名}.styles.css ファイルを生成します。このファイルへの参照パスは wwwroot/index.html(Blazor WebAssembly)または Pages/_Layout.cshtml(Blazor Server)の <head> タグ内にあります。ビルド時に生成されるため、プロジェクト内には表示されませんが、ブラウザの Dev tool を開いて Sources タブに切り替えると、このファイルを確認できます。

クラスの後ろに見慣れない文字列が付いていることに気づくかもしれません。例えば .page[b-mxoy4q7bj7].main[b-mxoy4q7bj7] などです。これは Blazor が CSS セレクターがどのコンポーネントに適用されるかを識別するためのスコープ識別子で、形式は b- に続く10桁の数字と英字です。各コンポーネントのスコープ識別子は一意です。したがって、この .main および .page クラスは [b-mxoy4q7bj7] に対応するコンポーネントにのみ作用することがわかります。コメントには /* _content/BlazorServer/Shared/MainLayout.razor.rz.scp.css */ と書かれており、Shared/MainLayout.razor.css を開くと確かに .main.page クラスがあります。rz.scp.css という拡張子は、CSS セレクターがどのコンポーネントに属するかを識別するために使われます。

次に Blog.razor.csslabel に対するスタイル変更を追加し、Ctrl + Shift + B でプロジェクトをビルドしてから Web ページを確認すると、文字色が変わっていることがわかります。BlazorServer.styles.css の中でも Blog.razor.rz.scp.css のスタイルブロックに label[b-0ae5hiw99t] が追加されています。

子コンポーネントへのスタイル適用

Post コンポーネントの label 要素にも同じスタイルを適用したいが、それぞれに razor.css ファイルを作りたくない場合はどうすればよいでしょうか?Blazor では便利な方法が用意されており、CSS セレクターの前に ::deep を付けるだけです。Blog.razor.css の label の前に ::deep を追加すると、Post の label 要素の文字色もすべて変わります。BlazorServer.styles.css のクラスも label[b-0ae5hiw99t] から [b-0ae5hiw99t] label に変わります。

ただし、::deep が有効になるには親子関係が必要です。親コンポーネントのスコープ識別子は <div> タグにのみ作用します。子コンポーネントが <div> タグで囲まれていない場合は効果がありません。Blog.razor で Post コンポーネントを囲んでいる <div> タグをコメントアウトして保存し、Web ページを確認すると、<label> の文字色がすべて黒に戻ります。しかし BlazorServer.styles.css のクラスは依然として [b-0ae5hiw99t] label のままです。

参照:

  1. ASP.NET Core Blazor CSS isolation

注: 本稿のコードは .NET 6 + Visual Studio 2022 でリファクタリングされています。原文リンクとリファクタリング後のコードを比較しながらお読みいただくことをおすすめします。ご一読いただき、原作者へのご支援をお願いいたします。

さらに探索

関連読書

その他の記事
同じカテゴリ / 同じタグ 2021/12/25

(29/30)みんなで学ぶBlazor:Blazor単体テスト

システム開発において最も退屈なプロセスは、おそらくバグ修正です。特に、null オブジェクトにアクセスしようとするエラー(`Object reference not set to an instance of an object.`)は、多くの初心者が最初に直面する問題です。退屈なバグ修正から解放されるために、この記事では「単体テスト」を紹介します。

続きを読む
同じカテゴリ / 同じタグ 2021/12/25

(28/30)みんなで学ぶBlazor:ポリシーベースの認可

以前に「ASP.NET Core Identity」は「Claim」ベースの検証を使用すると述べましたが、実は「ASP.NET Core Identity」には異なる種類の認可方法があります。最も簡単な「ログイン認可」「ロール認可」「Claim認可」ですが、これらはすべて同じ方法で実現されています:原則認可(ポリシーベースの認可)です。

続きを読む