Quick answer: Set every per-state StyleBox key in the Theme’s Button section: normal, hover, pressed, disabled, focus. Skipping any falls back to defaults. Use Theme Type Variation (e.g. ButtonDanger) for stylistic variants without rebuilding all five styleboxes.

You design a beautiful Button stylebox in your Theme. The button looks correct at rest. Hover or click and the default gray flashbox appears. The Theme has six stylebox slots and you only filled one.

The Symptom

Custom Button styling appears only in the idle state. Hover, pressed, disabled, and focus states show the engine defaults. Or the focus rectangle clashes with a custom focus outline.

The Theme Slots

Each Button-derived control has a Theme section listing every customizable resource. For Button:

StyleBox:
  normal      # default state
  hover       # mouse over, not pressed
  pressed     # mouse held down
  disabled    # control disabled
  focus       # keyboard focus indicator
  hover_pressed
Color:
  font_color, font_color_hover, font_color_pressed, ...
Font / FontSize / Constants: ...

Each slot is independent. Set normal alone: only normal looks right. The fix is to set them all.

The Fix

Step 1: Open the Theme. Either the project-wide theme or a custom Theme Resource. Click + on the Button type if not added. Expand StyleBox.

Step 2: Set every state. For each state, click +, pick StyleBoxFlat (or your StyleBoxTexture). Configure colors and borders.

Quickest workflow: design the normal stylebox, right-click it, Duplicate, paste into hover (with brighter bg), pressed (darker bg), disabled (gray), focus (outline only).

Step 3: Verify font color per state. Don’t forget font_color_hover, font_color_pressed, etc. White text on hover and unchanged dark text on pressed looks broken; bring those colors with the styleboxes.

Theme Type Variation

For variants like “Danger Button” (red theme):

Theme:
  Button (base, neutral colors)
  ButtonDanger:                # variation, base = Button
    StyleBox/normal:           red flat
    StyleBox/hover:            brighter red
    Color/font_color:          white

On the button instance: theme_type_variation = ButtonDanger. The control looks for ButtonDanger overrides first, falls back to Button.

Programmatic Overrides

For one-off styling without polluting the Theme:

$Button.add_theme_stylebox_override("normal", my_stylebox)
$Button.add_theme_color_override("font_color", Color.RED)

Verifying

Run the scene. Mouse over the button: hover style. Click: pressed style. Tab to focus: focus outline. Disable via code: disabled style. All four should look intentional.

“Five states, five styleboxes. Variations layer over base. UI feels coherent.”

Related Issues

For Control anchor on resize, see anchor. For RichTextLabel parsing, see BBCode.

Five styleboxes. Variation for variants. UI looks done.