Follow these best practices when you write USS to style visual elements.
Use USS files instead of inline styles when you can for more efficient memory usage.
Inline styles are per element and can cause memory overhead. When you use inline styles in a C# script or a UXML file on many elements, the memory usage becomes high quickly.
All USS selectors are applied at runtime so the architecture affects initialization performance. USS selectors are applied when an element first appears or when its classes change:
:hover
selector is the main culprit for selectors to cause interactivity issues and a re-styling.Usually, it’s not a problem if you have a lot of selectors because each USS file is turned into a lookup table. However, the performance decreases linearly as you add classes to an element. Each class in the list is used to query the lookup table. The complexity is N1 x N2
, where:
N1
is the number of class on the elementN2
is the current number of applicable USS filesThe number of elements in the hierarchy is the main fact that affects performance. Update Styling might be negligible for simple UIs but is significant for large UIs that have several thousands of elements. If an element matches a lot of selectors, it causes overhead to merge the styles coming from each rule.
In general, complex selectors have more impact on performance than simple selectors. Complex selectors depend on the ancestors of an element to match it. When possible, consider the following:
selector1 > selector2 > selector3
) instead of the descendant selector (selector1 selector2 selector3
).selector1 > selector2 > *
) or the combination of descendant selector with the universal selector (selector1 * selector2
). The universal selector tests every potential element against the selector which can impact performance.:hover
pseudo-class in selectors on elements with many descendants, such as .yellow:hover > * > Button
. Mouse movements invalidate the entire hierarchy of elements targeted by an :hover
selector.You can use the Block Element Modifier(BEM) convention to reduce hierarchical selectors. With BEM, each element receives a class that combines its specific existence inside another element.
BEM は Block Element Modifier の略です。BEM はシンプルなシステムで、構造化され、あいまいでない、メンテナンスが簡単なセレクターを作成するのに役立ちます。BEM では、要素にクラスを割り当て、それらのクラスをスタイルシートのセレクターとして使用します。
BEM クラスには最大 3 つのコンポーネントがあります。
menu
、button
、list-view
menu**item
、 button**icon
、list-view__item
menu--disabled
、menu**item--disabled
、button--small
、list-view**item--selected
名前の各部分は、アルファベット文字、数字、ダッシュで構成されます。名前の各部分は、ダブルアンダースコア __
またはダブルダッシュ --
でつながれます。
The following example shows UXML code for a menu:
<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>
Each element is equipped with classes that describe its role and appearance, you can write most of your selectors with only one class name:
.menu {
}
.menu__item {
}
.menu__item--disabled {
}
You can style elements with a single class name. Sometimes, you might need to use complex selectors. For example, you can use a complex selector when the style of an element depends on the modifier of its block:
.button {
}
.button__icon {
}
.button--small {
}
.button--small .button__icon {
}
ノート:
Button
, Label
) or element names (#my-button
) in your BEM selectors.UI Toolkit は BEM に準拠しています。各ビジュアル要素には、必要なクラス名が付けられています。例えば、すべての TextElement
には、 unity-text-element
クラスがあります。TextElement
から派生した Button
の各インスタンスは、そのクラスリストに unity-button
と unity-text-element
クラスが含まれます。
VisualElement
またはその子孫の 1 つから新しい要素を派生させる場合は、以下のガイドラインに従って、BEM 手法を使用して要素のスタイルを簡単に設定できます。
AddToClassList()
を使用して、関連する USS クラスを要素インスタンスに追加します。my-block**first-child
、my-block**other-child