Unity Style Sheet (USS)

USS檔案以.uss為副檔名,它是一個文字檔,可以定義UI共用的風格(style),讓App更容易管理整體的風格。
一個USS會包含以下

  • Style rules:一個style rule會有一個selector與一個declaration block。
    • Selector定義了哪些visual element會應用這個style rule
    • Declaration block:使用角括弧(curly braces),在其中可以定義多個style。
      • 每個sytle都會有一個property與value,並在結尾要加上一個分號(semi-colon)

句法如下

1
2
3
4
selector {
property1: value;
property2: value;
}

例子

1
2
3
Button {
width: 200px;
}

Type selector:會挑選符合對應C#或是visual element type的elements

1
2
3
4
Button {
border-radius: 8px;
width: 100px;
}

注意以下是不合法的Type selector

1
2
3
UnityEngine.UIElements.Button { 
...
}

Class selector:會挑選有指定該USS class的elements。

在class的命名中:

  • 在名字中不要有英文句號
    • 假設一個class名為yellow.button,在建立USS規則(USS rule)的話會這樣使用.yellow.button{...},這樣會被當成yellowbutton兩個class
  • 不可以以數字作為開頭
  • class名稱是大小寫敏感的(case-sensitive)
  • USS中,class selector要以英文句號 . (period)開頭
  • UXML中,只需設定class名稱,如:class="yellow"即可

下面定義了一個 yellow class selector rule,注意它前面有一個英文句號(period),

1
2
3
.yellow {
background-color: yellow;
}

在UXML中要使用的話,使用class="名稱"例如:
<Button name="OK" class="yellow" text="OK" />

一個簡單的例子如下:

1
2
3
4
5
6
7
8
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

Name selector:會挑選name相符合的elements。(有點類似CSS中的ID selector)。

name的使用:

  • 為element設定name的方式有兩種
    1. 在C# script中使用 VisualElement.name
    2. 在UXML中使用 name 屬性,例如:<VisualElement name="my-nameName">.
  • 為了避免意外,name必須唯一。
  • 在USS中,name selector需要以 #(number sign) 開頭
    • 例如#ElementName { ... }
  • 在UXML中,只需設定class名稱,如:name="my-nameName"即可
    • `<Button name="#OK" />`這個是不合法的。
      

下面定義一個name為Cancel的name selector rule

1
2
3
4
5
#Cancel {
border-width: 2px;
border-color: DarkRed;
background-color: pink;
}

在UXML中使用的話,使用name="名稱"例如:<Button name="Cancel" text="Cancel" />

1
2
3
4
5
6
7
8
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

Universal selector:也稱為wildcard selector,它會匹配所有的element。

* (asterisk)為Universal selector

下面定義一個Universal selector

1
2
3
* {
background-color: yellow;
}

以下的UXML的所有element都會應用這個background-color: yellowstyle

1
2
3
4
5
6
7
8
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

Descendant selector:會在visual tree中選出匹配的後代elements。注意,使用這個selector比較消耗效能

語法如下:

1
selector1 selector2 {...}

例子:這個例子會選擇#container1之下含有yellow class的所有child elements。

1
2
3
4
#container1 .yellow {
background-color: yellow;
}

在UXML中的設定如下,#container1有一個child element,#container2class="yellow"

1
2
3
4
5
6
7
8
9
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

結果如下圖,#container2#OK以及#Cancel的背景色都被改變了,但#container1的背景沒有被改變


Child selector:會在visual tree中選出匹配的child elements。

語法如下:

1
selector1 > selector2 {...}

例子:這個例子會選擇#container1的child中含有yellow class的所有child elements。

1
2
3
4
#container1 > .yellow {
background-color: yellow;
}

在UXML中的設定如下,

1
2
3
4
5
6
7
8
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

這個的child selector style rule 只會匹配到#container2

  • 這是因為#container2#container1的child element,並且含有yellow class。
  • #OK#Cancel不匹配的原因是因為它們是屬於#container2的child而不直接的屬於#container1的child,所以匹配不到。

你也可以把wildcard selector使用在這些複雜的selector,例如以下這個selector rule,它會找出yellow class下的所有Button element

1
.yellow > * > Button{..}

Multiple selector:Multiple selector是組合多個simple selector它會選出符合simple selector的elements。

以下是語法

1
selector1selector2 {...}

如果Multiple selector區分不出selector的話,會把它們當作一個,例如ListViewButton這兩個type selector,若想使用Multiple selector會變成下面這樣

1
ListViewButton{...}

USS parser無法辨識出它是兩個selector,會把它當作一個ListViewButton
因為Class與Name selector有一個前綴詞(分別是.#),所以可以辨認出來,而Type selector沒有,所以在使用Multiple selector若是想要用Type selector的話,Type selector必須放到第一個。

1
ListView.yellow#vertical-list{...}

在下面這個例子中,最後會選出來的是<Button name="OK" class="yellow" text="OK" />

1
2
3
Button.yellow {
background-color: yellow;
}
1
2
3
4
5
6
7
8
<UXML xmlns="UnityEngine.UIElements">
<VisualElement name="container1">
<VisualElement name="container2" class="yellow">
<Button name="OK" class="yellow" text="OK" />
<Button name="Cancel" text="Cancel" />
</VisualElement>
</VisualElement>
</UXML>

Reference: https://docs.unity3d.com/Manual/UIE-about-uss.html

評論