Changes in USS stylesheet breaks game in editor

When using Unity-2022-3-LTS I could make updates to my .uss stylesheets and the changes was immediately reflected in the game window. Using Unity Unity-2023-2 and Unity-2023-3 changes in the stylesheet breaks the preview.

Or to be precise: the changes are reflected in the Game view for a split second but immediately thereafter all of the elements that are code generated disappears from the screen. The remaining UI Elements, like navigation buttons that loads directly from the .uxml file, are still in place but clicking them triggers no actions.

I’ve tried this in a really simple setup:

The game has a Canvas
The Canvas has an UIDocument
The UIDocument has a stylesheet, a controller and a simple UXML asset that contains:

  • VisualElement "menu" with a button
  • VisualElement "content" that is empty

The controller has this method:

void Start()
{
    var root = GetComponent<UIDocument>().rootVisualElement;
    var content = root.Q<VisualElement>("content");
    var testButton = root.Q<Button>("test-button");
    testButton.clicked += () => { Debug.Log("Test Button Clicked"); };
    Label testLabel = new("This is my label") { name = "test-label" };
    content.Add(testLabel);
}

Starting the game everything works as expected. The test label is added to the content Visual Element. The button responds to click.

Now, changing the stylesheet, the changes appears for a split second. Then the added label disappears and the button no longer responds to click.

Is it supposed to behave in this way? If so, designing the UI becomes extremely frustrating.

Try using OnEnable instead

[SerializeField] UIDocument _uiDocument;

void OnEnable () => Bind( _uiDocument.rootVisualElement );
void OnDisable () => Unbind( _uiDocument.rootVisualElement );

void Bind ( VisualElement root )
{
    // bind your UI here
}
void Unbind ( VisualElement root )
{
    // optional
}

Note:

If this won’t be enough then Bind again after this stylesheet change. This is because mayor operations like that will force the VisualElement tree to be cleared and rebuilt from scratch - this is by design and makes sense if you think through alternatives.