The minimum UI Toolkit knowledge needed to read Luna code and USS files. Already know UITK? Skip to Why UI Toolkit? for the comparison, or Theme Stack for Luna's theme model.
UI Toolkit is Unity's newer UI system, modeled on web tech (HTML/CSS/DOM). Three layers split structure, style, and behavior — same as the web:
UXML → structure (the visual tree)
USS → style (selectors + properties; cascades like CSS)
C# → behavior (event callbacks, dynamic state).class, #name, type, and pseudo-class selectors. Inspired by CSS with Unity-specific overrides (-unity-… properties, image scale modes).@import to layer in further USS. One TSS per project.Composition: a UIDocument loads a .uxml; its Panel Settings resolves the .tss; the TSS imports .uss files; selectors target elements in the visual tree.
Layout is flexbox. Direction (flex-direction: row | column), grow (flex-grow), wrap, justify, align — same axes and rules as CSS flexbox. No RectTransform anchors. Coming from uGUI, expect a brief re-learn: parents distribute space to children via flex rules instead of children pinning to parent edges via anchors.
Load a UXML clone, then query elements by name or class:
var root = uiDocument.rootVisualElement;
var btn = root.Q<Button>("submit-btn"); // single element by name
var rows = root.Query<VisualElement>(className: "row").ToList();Q<T>() is the workhorse. Luna sample code uses it everywhere.
Don't mutate inline style at runtime if you can avoid it. Toggle a CSS class instead, and let the stylesheet describe what that state looks like:
element.AddToClassList("active");
element.RemoveFromClassList("active");
element.EnableInClassList("disabled", isDisabled); // conditional
element.ClassListContains("active");.button { background-color: var(--color-primary-500); }
.button.active { background-color: var(--color-primary-700); }Luna components use this pattern pervasively — responsive breakpoints (.breakpoint-lg), locale switches (.locale-ja), drag state, etc.
:hover, :active, :focus, :checked, :disabled, :root. Style states declaratively in USS instead of writing hover/leave callbacks.
--…)Custom properties (CSS variables) declared on a selector (commonly :root for globals) and referenced with var(--name). Inherit down the tree:
:root {
--color-primary-500: #a855f7;
--radius-md: 8px;
}
.button {
background-color: var(--color-primary-500);
border-radius: var(--radius-md);
}Luna's whole theming model is USS variables — every color, every spacing, every font is a var(--…) reference into LunaUIDemoTheme.tss. Override the variables in your own USS to retheme without touching component selectors.
UI Toolkit has its own event system. It is not Button.onClick or UnityEvent — those are uGUI / Inspector wiring. Use RegisterCallback<T>:
btn.RegisterCallback<ClickEvent>(evt => Debug.Log("clicked"));
slider.RegisterValueChangedCallback(evt => Debug.Log(evt.newValue));
input.RegisterCallback<KeyDownEvent>(evt => { /* … */ });Events propagate in three phases: trickle-down (root → target), target, bubble-up (target → root). Same model as DOM events. Stop propagation with evt.StopPropagation().
UITK uses SDF (signed distance field) fonts for crisp scaling at any size. The Panel Settings → Text Settings asset configures the font fallback chain — what to render when a glyph isn't in the primary font (Japanese, emoji, missing symbols). Luna's UITextSettings.asset in Essentials wires the Luna font set; extend it instead of replacing it when you add a language.
background-image: url("..."); accepts both Texture2D and Sprite. Sprites with import-settings borders 9-slice automatically via -unity-slice-{left,right,top,bottom} properties. Luna uses this for buttons, panels, progress bars.
Window > UI Toolkit > UI Builder).Window > UI Toolkit > Debugger).Both are worth opening once; neither is required.
Now that you know how UITK works in general, see how Luna layers a theme on top: Theme Stack explains Panel Settings configuration, the @import chain from Unity's defaults through Luna's main theme to your overrides, and how to customise colors / fonts without forking the package.
Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction