Skip to content

3. Layouts and stylesheets

Joni Savolainen edited this page Jun 2, 2023 · 2 revisions

Layouts

LayoutAttribute

[Layout] allows specifying the path to a UXML file. The file will be loaded automatically. A component can have a single [Layout] attribute. It can be inherited from a parent class.

[Layout("Assets/LayoutOne.uxml")]
public partial class UIComponentWithLayout : UIComponent {}

public partial class UIComponentWithSameLayout : UIComponentWithLayout
{
    // Uses Assets/LayoutOne.uxml
}

[Layout("Assets/LayoutTwo.uxml")]
public partial class UIComponentWithOverriddenLayout : UIComponentWithLayout
{
    // Uses Assets/LayoutTwo.uxml
}

Stylesheets

StylesheetAttribute

[Stylesheet] allows specifying paths to USS files. The files will be loaded automatically. Unlike [Layout], multiple [Stylesheet] attributes can be used on a single UIComponent.

[Stylesheet("Assets/StylesheetOne.uss")]
[Stylesheet("Assets/StylesheetTwo.uss")]
public partial class UIComponentWithTwoStylesheets : UIComponent {}
        
[Stylesheet("Assets/StylesheetThree.uss")]
public partial class ChildComponent : UIComponentWithTwoStylesheets {}

Stylesheets will be applied to ChildComponent in the following order:

  • Assets/StylesheetOne.uss
  • Assets/StylesheetTwo.uss
  • Assets/StylesheetThree.uss

This means that child components can override styles from their parents.

RootClassAttribute

You may need to add USS classes to the root element of your UIComponent:

/* Common.uss */

.root {
    background-color: #ff0000;
}
[Stylesheet("Common")]
public partial class UIComponentWithRootClass : UIComponent
{
    public override void OnInit()
    {
        this.AddToClassList("root");
    }
}

[RootClass] allows specifying the name of a class that will be added to the root element of the UIComponent. You do not need to use OnInit with it.

[Stylesheet("Common")]
[RootClass("root")]
public partial class UIComponentWithRootClass : UIComponent {}

QueryAttribute

[Query] generates Query calls automatically for you. You can query for a single element or many at once.

<!-- Resources/MyLayout.uxml -->
<UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Label name="hello-world-label" text="Hello world!" class="text" />
    <ui:Foldout name="test-foldout">
        <ui:Label name="foldout-content" text="Foldout content" class="text" />
    </ui:Foldout>
</UXML>
[Layout("MyLayout")]
public partial class MyComponent : UIComponent
{
    [Query("hello-world-label")]
    public Label HelloWorldLabel;
            
    [Query(Name = "test-foldout")]
    public Foldout TestFoldout;
    
    [Query]
    public Label FirstLabel;
    
    [Query(Class = "text")]
    public Label[] LabelsWithTextClass;
    
    [Query(Name = "hello-world-label", Class = "text")]
    public Label HelloWorldLabelWithTextClass;
    
    [Query]
    public List<Label> AllLabelsImplicit;
    
    [Query(Name = "hello-world-label")]
    [Query(Name = "foldout-content")]
    public List<Label> AllLabelsExplicit;
    
    public override void OnInit()
    {
        HelloWorldLabel.text = "Goodbye world!";
        TestFoldout.Add(new Label("More content!"));
    }
}

[Query] only works on fields that are assignable to VisualElement. Others are ignored.