Skip to Content
Mix 2.0 is in development! You can access the Mix 1.0 docs here.
DocsGuidesDynamic Styling

Dynamic Styling

Traditionally, making your widgets react to different states—like being pressed, hovered, disabled, or adapting to dark mode—means scattering conditional logic and style changes throughout your widget tree. This quickly becomes verbose and hard to maintain, as you end up writing a lot of boilerplate just to update colors, borders, or other properties based on the widget’s state or context. Mix streamlines this process by letting you define context-aware variants in a single place, so your styles automatically adapt to any situation without cluttering your UI code.

Understanding Variants

Let’s look at a simple example: suppose you want a Box to change its color when hovered. With Mix, you can achieve this by simply adding .onHovered(...) to your style definition.

final style = BoxStyler() .color(Colors.red) .height(100) .width(100) .borderRounded(10) .onHovered(BoxStyler().color(Colors.blue));

Note that wasn’t necessary to define the height, width, and border radius. Mix will automatically merge the style inside the .onHovered(...) method with the previous style. Making your code less verbose, much easier to read and maintain.

Composing Styles with Variants

When you define a style, it is expected to be reused in multiple places. With Mix, you can easily reuse styles even when a variant was defined inside it.

final styleA = BoxStyler() .color(Colors.red) .height(100) .width(100) .borderRounded(10) .onHovered( BoxStyler() .color(Colors.blue) .width(200) ); final styleB = styleA.onHovered(BoxStyler().color(Colors.green));

In this example, styleB will have the same style as styleA, but when the widget is hovered it has a different color and maintains the width equal to 200. So the final style when hovered will be:

BoxStyler() .color(Colors.green) .height(100) .width(200) .borderRounded(10);

Nesting Variants

There are cases where you want to combine multiple variants to achieve a specific style. For example, you want to apply a variant when the widget is hovered and want different colors for dark mode and light mode. With Mix, you can achieve this by simply nesting the variants.

final hoverStyle = BoxStyler() .onDark(BoxStyler().color(Colors.blue)) .onLight(BoxStyler().color(Colors.green)); final style = BoxStyler() .color(Colors.red) .height(100) .width(100) .borderRounded(10) .onHovered(hoverStyle);

Built-in Variants

Built-in Variant Methods

Below is a list of all built-in variant methods available on stylers (e.g., BoxStyler, TextStyler). Each method allows you to apply a style based on a specific state, platform, breakpoint, or context.

MethodDescription
onHovered(style)Applies style when the widget is hovered
onPressed(style)Applies style when the widget is pressed
onFocused(style)Applies style when the widget is focused
onDisabled(style)Applies style when the widget is disabled
onSelected(style)Applies style when the widget is selected
onError(style)Applies style when the widget is in an error state
onScrolledUnder(style)Applies style when the widget is scrolled under
onDragged(style)Applies style when the widget is being dragged
onEnabled(style)Applies style when the widget is enabled (not disabled)
onDark(style)Applies style in dark mode
onLight(style)Applies style in light mode
onPortrait(style)Applies style in portrait orientation
onLandscape(style)Applies style in landscape orientation
onBreakpoint(breakpoint, style)Applies style for a custom breakpoint
onMobile(style)Applies style on mobile devices
onTablet(style)Applies style on tablets
onDesktop(style)Applies style on desktops
onLtr(style)Applies style for left-to-right text direction
onRtl(style)Applies style for right-to-left text direction
onIos(style)Applies style on iOS
onAndroid(style)Applies style on Android
onMacos(style)Applies style on macOS
onWindows(style)Applies style on Windows
onLinux(style)Applies style on Linux
onFuchsia(style)Applies style on Fuchsia
onWeb(style)Applies style on web
onNot(contextVariant, style)Applies style when the given context variant is not active
onBuilder((context) => style)Applies a style based on a custom function using BuildContext