Version: 2023.2
言語: 日本語
C# スクリプトでスタイルを適用する
テーマスタイルシート (TSS)

USS のベストプラクティス

USS の記述によってビジュアル要素のスタイル設定を行うにあたっては、以下に挙げるベストプラクティス (推奨される方法) に従ってください。

インラインスタイルを避ける

メモリを効率的に使用するために、できる限り、インラインスタイルではなく USS ファイルを使用してください。

インラインスタイルは要素単位であるため、メモリのオーバーヘッドを引き起こす可能性があります。C# スクリプトや UXML ファイルで多くの要素にインラインスタイルを使用すると、メモリ使用量がすぐに増加します。

セレクターのアーキテクチャに関する考慮事項

全ての USS セレクターはランタイムに適用されるため、アーキテクチャが初期化のパフォーマンスに影響します。USS セレクターは、要素が初めて現れた時やクラスが変更された時に適用されます。

  • セレクターが相互作用に関する問題やスタイル変更を引き起こす主な原因は、:hover セレクターです。
  • パフォーマンスへの影響は、プロファイラーUpdate Styling の下に表示されます。

各 USS ファイルがルックアップテーブルになるため、通常は、セレクターが多数あることは問題ありません。ただし、要素にクラスを追加するとパフォーマンスは直線的に低下します。リスト内の各クラスは、ルックアップテーブルへのクエリに使用されます。N1 x N2 (以下参照) が複雑さになります。

  • N1 は要素の持つクラス数です。
  • N2 は、現在の該当 USS ファイル数です。

パフォーマンスに影響を与える主な要因は、階層内の要素の数です。Update Styling は、単純な UI では無視できるかもしれませんが、数千の要素がある大規模な UI では重要です。ある要素が多くのセレクターに一致する場合、各規則から来るスタイルをマージする際のオーバーヘッドが発生します。

複合セレクターの階層のガイドライン

一般的に、複合セレクターは単純セレクターよりもパフォーマンスに影響を与えます。複合セレクターは、要素を照合するにあたってその祖先に依存します。可能な限り、以下を検討してください。

  • 部分一致が必要な場合は、子孫セレクター (selector1 selector2 selector3) ではなく 子セレクター (selector1 > selector2 > selector3) を使用してください。
  • 複合セレクターの終わりにユニバーサルセレクターを使用 (selector1 > selector2 > *) したり、子孫セレクターとユニバーサルセレクターを組み合わせる (selector1 * selector2) ことは避けてください。ユニバーサルセレクターは、考えられる全ての要素をセレクターに照らし合わせてテストするので、パフォーマンスに影響する可能性があります。
  • 多数の子孫を持つ要素のためのセレクターに :hover 擬似クラスを使用することは避けてください (例: .yellow:hover > * > Button)。マウスの動きが、:hover セレクターのターゲットになっている要素の階層全体を無効化します。

BEM を使用してパフォーマンスを向上させる

Block Element Modifier (BEM) 規則を使用すると、階層的なセレクターを減らすことができます。BEM を使用した場合、各要素が、その特定の存在を別の要素内で組み合わせるクラスを受け取ります。

BEM について

BEM は Block Element Modifier の略です。BEM はシンプルなシステムで、構造化され、あいまいでない、メンテナンスが簡単なセレクターを作成するのに役立ちます。BEM では、要素にクラスを割り当て、それらのクラスをスタイルシートのセレクターとして使用します。

BEM クラスには最大 3 つのコンポーネントがあります。

  • ブロック名: ブロックは意味のあるスタンドアロンのエンティティまたは制御です。例: menubuttonlist-view
  • 要素名: スタンドアロンの意味を持たず、意味的にそのブロックに関連付けられているブロックの一部。要素名は 2 つのアンダースコアを使ってブロック名に追加されます。例: menu**itembutton**iconlist-view__item
  • モディファイア: ブロックや要素の外観や動作を変更するフラグ。モディファイアは 2 つのダッシュを使ってブロックまたは要素名に追加されます。例: menu--disabledmenu**item--disabledbutton--smalllist-view**item--selected

名前の各部分は、アルファベット文字、数字、ダッシュで構成されます。名前の各部分は、ダブルアンダースコア __ またはダブルダッシュ -- でつながれます。

以下の例は、 メニュー用の UXML コードを示したものです。

<VisualElement class="menu">
    <Label class="menu__item" text="Banana" />
    <Label class="menu__item" text="Apple" />
    <Label class="menu__item menu__item--disabled" text="Orange" />
</VisualElement>

各要素がその役割と見た目を説明するクラスを備えているため、ほとんどのセレクターは 1 つのクラス名で記述できます。

.menu {
}

.menu__item {
}

.menu__item--disabled {
}

要素のスタイル設定は 1 つのクラス名で行えます。複合セレクターの使用が必要な場合もあります。例えば、要素のスタイルがそのブロックの修飾子に依存する場合は、複合セレクターが使用できます。

.button {
}

.button__icon {
}

.button--small {
}

.button--small .button__icon {
}

ノート:

  • 長いセレクターの指定は避けてください。長いセレクターは、UI のグラフィックデザインに矛盾があることを示す可能性があります。
  • BEM セレクター内で型名 (Button, Label) や要素名 (#my-button) を使用しないでください。

ビジュアル要素を BEM に準拠したものにする

UI Toolkit は BEM に準拠しています。各ビジュアル要素に、必要なクラス名がアタッチされます。例えば、全ての TextElement には unity-text-element クラスがあります。TextElement から派生する Button の各インスタンスには、unity-button および unity-text-element クラスを含むクラスリストがあります。

VisualElement またはその子孫の 1 つから新しい要素を派生させる場合は、以下のガイドラインに従って、BEM 手法を使用して要素のスタイルを簡単に設定できます。

  • コンストラクターで AddToClassList() を使用して、関連する USS クラスを要素インスタンスに追加します。
  • 新しい要素がコンストラクターで子要素をインスタンス化する場合は、関連するクラスを子に割り当てます。例: my-block**first-childmy-block**other-child
  • 要素が複数の状態やバリアント (小さいや大きいなど) をサポートする場合は、要素の状態が変化するときや要素のバリアントが選択されるときに、関連するクラスを追加、または、削除します。
  • この要素を他のプロジェクトで使用する場合は、既存のユーザークラス名との競合を避けるために、クラスにプレフィックスを付けることを検討してください。

その他の参考資料

C# スクリプトでスタイルを適用する
テーマスタイルシート (TSS)