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 表示块元素修饰符。BEM 是一个简单的系统,有助于编写结构化、明确、易于维护的选择器。通过 BEM 可以向元素分配类,然后将这些类用作样式表中的选择器。
BEM 类最多包含三个组件:
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 工具包遵循 BEM。每个视觉元素都附有必要的类名。例如,所有 TextElement
具有 unity-text-element
类。从 TextElement
派生的 Button
的每个实例在类列表中都填充有 unity-button
和 unity-text-element
类。
如果从 VisualElement
或其某个后代派生新元素,请遵循以下准则以确保元素易于使用 BEM 方法进行样式设置:
AddToClassList()
,将相关 USS 类添加到元素实例。my-block__first-child
、my-block__other-child
。