On this page

StyleKit Property Resolution

A style property — such as background.color — can have many different values depending on the control's state, the active Theme, and effective style variations. For example, it can differ between the pressed and hovered states, or between the light and dark themes. This document details how StyleKit resolves the value a property will get when used for styling a particular Control.

Control States

Controls change appearance depending on interaction — hovered, pressed, checked, focused, disabled, and so on. When resolving a property, StyleKit exhausts all state-specific values first, before checking the normal state.

For example, if a Button is hovered, hovered.button.background.color is checked before button.background.color. And if it's also pressed, pressed.button.background.color is checked before them both. The order of precedence between states is documented in the ControlStateStyle documentation.

States can also be nested. A combination such as pressed.hovered.button.background.color is more specific than either pressed.button.background.color or hovered.button.background.color alone, and takes precedence over both.

Fallback Properties

Some style properties can be set more than one way. For example, the top-left radius on the background can be set either directly using background.topLeftRadius, or indirectly using background.radius (which sets all corners to the same radius). For such properties, StyleKit checks the specific property first, then the fallback, and exhausts both within the current state before moving to a less specific state. For example, button.hovered.background.radius takes precedence over button.background.topLeftRadius, if the control is hovered. And of course, button.hovered.background.topLeftRadius takes precedence over both.

Control Type Hierarchy

The controls form a hierarchy. A button falls back to abstractButton, which falls back to control. A groupBox falls back to frame, which falls back to pane, which falls back to control, and so on. control is the root type in the hierarchy, mirroring the type hierarchy of Qt Quick Controls. Refer to the documentation for each control type to see its direct fallback type.

When all states and fallback properties have been exhausted for a specific control type, StyleKit walks up the hierarchy to check whether it is set in a base type. For example, if button.background.color is not set, StyleKit will check abstractButton.background.color instead, and so on. This motivates the designer to factor the property values that are common across multiple controls into a common base type, to maximize reuse and minimize duplication. For example, you can put all the property values common to buttons, checkboxes, and radio buttons in abstractButton, and only set the properties that differ in the specific subtypes.

Note that any state (including the normal state) in a more specific type takes precedence over any state in a base type. For example, button.background.color takes precedence over hovered.abstractButton.background.color, even if the control is hovered. And of course, hovered.button.background.color takes precedence over both.

Style And Theme

The Control Type Hierarchy is repeated inside both a Style and a Theme. When resolving a property, StyleKit first looks through the control type hierarchy in the active Theme, then in the active Style. This means that properties set in the active theme take precedence over those set in the style. As a consequence, a base type in the theme also overrides a more specific type in the style. For example, theme.control.background.color takes precedence over style.button.background.color.

Style Variations

The Control Type Hierarchy is repeated inside a StyleVariation. Style variations can be defined both in a style and in a theme, and a style variation in a theme takes precedence over the theme itself. Since a theme takes precedence over a style, the style properties in the current theme will also take precedence over style variations in the style. For example, theme.button.background.color takes precedence over style.variation.button.background.color.

Fallback Style

Every Style has a fallback style — a complete style that acts as a last resort when a property cannot be resolved within the active style. If the full resolution process (across control types, states, the active theme, and any style variations) fails to find a value, StyleKit repeats the entire process in the fallback style. The default fallback style looks similar to the Basic Style, so even an empty style will still produce fully styled controls.

The fallback style can itself have a fallback style, and StyleKit follows this chain recursively until it either finds a value or exhausts the chain. If no value is found, a default value is used.

Putting It All Together

As an example, let's say StyleKit needs to resolve background.color for a hovered Button. The style has a theme, and both the style and the theme have an active variation. StyleKit then checks the following locations in order, using the first value it finds:

  • theme.variation.hovered.button.background.color
  • theme.variation.button.background.color
  • theme.variation.hovered.abstractButton.background.color
  • theme.variation.abstractButton.background.color
  • theme.variation.hovered.control.background.color
  • theme.variation.control.background.color
  • theme.hovered.button.background.color
  • theme.button.background.color
  • theme.hovered.abstractButton.background.color
  • theme.abstractButton.background.color
  • theme.hovered.control.background.color
  • theme.control.background.color
  • style.variation.hovered.button.background.color
  • style.variation.button.background.color
  • style.variation.hovered.abstractButton.background.color
  • style.variation.abstractButton.background.color
  • style.variation.hovered.control.background.color
  • style.variation.control.background.color
  • style.hovered.button.background.color
  • style.button.background.color
  • style.hovered.abstractButton.background.color
  • style.abstractButton.background.color
  • style.hovered.control.background.color
  • style.control.background.color

If all these locations are exhausted without finding a value, the same process is repeated in the fallback style (recursively, if the fallback style also has a fallback style). If still not found, a default value is used.

Debugging Property Resolution

With multiple control types, themes, variations, and fallback styles all contributing to the final value of a property, it can sometimes be hard to tell why a particular control ends up with a particular appearance. StyleKitDebug is a diagnostic in-app tool that logs each style property read to the debug output, showing exactly which layer and control type a property was resolved from.

To start tracing, assign the control you want to introspect to the StyleKit.debug.control property:

ApplicationWindow {
    id: app
    width: 1024
    height: 800
    visible: true

    StyleKit.debug.control: someButton
    StyleKit.debug.filter: "background.color"

    StyleKit.style: Style {
        button {
            background.color: "gray"
            hovered.background.color: "dimgray"
        }
        dark: Theme {
            button {
                background.color: "skyblue"
                hovered.background.color: "lightblue"
            }
        }
    }

    Column {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        Button {
            id: someButton
            text: "A Button"
        }
    }
}

Each resolved property is printed as a single line, for example:

[read] StyleReader[Hovered].button.background.color -> Style.Theme(Dark).button[Hovered] = #add8e6

The StyleReader in the output refers to the StyleReader that the Button uses internally to read its style property values.

Use the filter property to limit the output to properties of interest.

Note: Enabling StyleKitDebug will severely degrade performance. Use it only during debugging.

See also Style, Theme, StyleVariation, StyleKitDebug, and StyleKit Features Overview.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.