Quick answer: Inspector “Theme Overrides” only affect the one node they are set on — they do not propagate. To style all children, assign a Theme resource to the parent’s theme property, or apply overrides per-node via add_theme_color_override() in a script.

You open the Inspector, go to the Theme Overrides tab on a Panel or VBoxContainer, set a custom font color — and the children look exactly the same. Or you set a project-wide theme in Project Settings and one stubborn Label refuses to follow it. Godot’s theme system has a clear inheritance hierarchy, but it has several non-obvious rules that cause exactly this frustration.

The Symptom

Common presentations of this bug:

What Causes This

Godot 4’s theme resolution works in a strict priority order. For any given theme item (color, font, stylebox, constant, icon), Godot checks these sources from highest to lowest priority:

  1. The node’s own Theme Overrides (Inspector tab or add_theme_*_override())
  2. The Theme resource assigned to the node itself
  3. The nearest ancestor’s Theme resource (walking up the tree)
  4. The project-wide default theme (Project Settings > GUI > Theme)
  5. Godot’s built-in default theme

The key insight: Theme Overrides are local to their node. They are not part of a Theme resource, they cannot propagate, and they cannot be inherited. If you set an override on a parent container, child nodes skip straight to step 2 and look for a Theme resource — they never see the parent’s local override.

The Fix: Use a Theme Resource on the Parent

To propagate styling to all descendants, create a Theme resource and assign it to the parent’s theme property. Child controls automatically inherit from the nearest ancestor that has a Theme resource assigned.

# In the Inspector on your root Control / Panel / VBoxContainer:
# theme = <new Theme resource>
# Edit the Theme resource to set fonts, colors, styleboxes.

# Via script, assign a pre-created Theme resource:
@export var ui_theme: Theme

func _ready() -> void:
    theme = ui_theme   # all children inherit from this

Open the Theme resource in the resource editor and set font, color, or stylebox values per control type (e.g. “Label”, “Button”). Every child of that type will pick up the theme automatically.

The Fix: Per-Node Overrides in Script

When you need to style a specific node at runtime — highlight a selected item, change a button’s color on hover — use the add_theme_*_override() API directly on that node:

func highlight(label: Label) -> void:
    label.add_theme_color_override("font_color", Color.YELLOW)
    label.add_theme_font_size_override("font_size", 18)

func reset_highlight(label: Label) -> void:
    # Remove override — node goes back to inheriting from Theme
    label.remove_theme_color_override("font_color")
    label.remove_theme_font_size_override("font_size")

func style_button(btn: Button) -> void:
    var sb = StyleBoxFlat.new()
    sb.bg_color = Color("#3a7bd5")
    sb.corner_radius_top_left = 6
    sb.corner_radius_top_right = 6
    sb.corner_radius_bottom_left = 6
    sb.corner_radius_bottom_right = 6
    btn.add_theme_stylebox_override("normal", sb)

Think of add_theme_color_override() as inline CSS — it wins over everything else for that specific node. Think of a Theme resource as a stylesheet that children inherit. The two serve different purposes and should not be confused.

Why a Child’s Own Override Wins Over the Parent’s Theme

If a child node has an override set (even from a previous call or from the Inspector), that override takes the highest priority and blocks the parent’s Theme resource from reaching it. This catches developers off guard when a node was styled during prototyping and then refused to follow the new project theme.

To check whether a node has an active override and clear it:

# Check if a theme override is currently set
if label.has_theme_color_override("font_color"):
    label.remove_theme_color_override("font_color")

# Remove all local overrides so the node inherits cleanly
func clear_all_overrides(control: Control) -> void:
    for color_name in ["font_color", "font_shadow_color"]:
        if control.has_theme_color_override(color_name):
            control.remove_theme_color_override(color_name)

Project-Wide Theme vs Node Theme

Godot allows you to set a default theme for the entire project under Project Settings > GUI > Theme > Custom. This acts as the fallback (priority 4 in the list above). Any node that does not have a local Theme resource in its ancestor chain will draw from this project theme. If a single node is ignoring the project theme, it almost always means a Theme resource or a local override is set somewhere on itself or an ancestor, taking precedence.

Use Scene > UI > Theme Debugger (available in the Godot editor’s bottom panel) to inspect which theme item is actually winning for any selected control node. This is the fastest way to find the override that is blocking your expected styling.

Related Issues

See also: Fix: Custom Fonts and Assets Not Loading in Godot Export.

See also: Fix: Godot Control Node Sizing and Anchor Confusion.

Inspector overrides style one node; Theme resources style a whole subtree — know which tool you need.