Skip to main content

How Conflicts Are Resolved

When two classes set the same style property, Uniwind picks the winner the same way a browser does. It compares, in this order:
  1. Importance - !important declarations beat normal ones
  2. Cascade layer - rules outside any @layer beat rules inside a layer. Between layers, the layer declared later wins (reversed for !important declarations)
  3. Selector specificity - more specific selectors win. Every class, state variant (active:, focus:, disabled:), and data attribute adds to specificity. Media queries, such as breakpoints and platform variants, don’t
  4. Source order - the rule that comes later in the compiled CSS wins
The order of classes inside className is never part of this comparison.
Cascade order on native requires Uniwind 1.13.0 or Uniwind Pro 1.9.0 or later. On web, the browser applies these rules in every version.
Upgrading from an older version? Before 1.13.0 (Pro 1.9.0), the last conflicting class in className won on native, so className="text-red-500 text-blue-500" was blue on native and red on web. It is now red on both. Check components that pass conflicting utilities and rely on their order.

Class Name Conflicts

Uniwind does not automatically deduplicate classNames. If you pass conflicting utilities for the same style property, the one Tailwind emits later in the generated CSS wins:
Result: Both backgrounds are red, because Tailwind emits bg-red-500 after bg-blue-500 in the generated CSS. Tailwind decides that order, not your className string. Use tailwind-merge when building className strings that may contain conflicts. It removes the earlier conflicting class, so the class you pass last wins:
Result: The background will be blue.
Use tailwind-merge for reusable components where consumer-provided classNames should override base styles predictably. See How do you handle merging and deduplicating classNames? for the cn setup.

State Variants

State variants add to selector specificity, so they override the base utility while the state is active, regardless of class order:
Result: Red by default, blue while pressed.

Important Utilities

Use Tailwind’s important modifier (!) when a utility must override another utility for the same property.
Result: The background will be red. This works the same as Tailwind CSS: bg-red-500! is generated with higher priority than bg-blue-500. When several important utilities conflict, specificity and source order decide between them, just like for normal utilities:
Result: Red by default, blue while focused.

Custom CSS Classes

Tailwind generates utilities inside @layer utilities. Custom classes you write directly in global.css are outside any layer, so they win over utilities that set the same property:
global.css
Result: The background will be white. To let utilities override a custom class, define it inside @layer components, which Tailwind declares before utilities:
global.css
Result: card bg-blue-500 now renders a blue background.

Inline Styles

Inline styles always have higher priority than className styles in Uniwind.
Result: The background will be blue.
Inline styles always have higher priority than className styles, even when the class uses the important modifier.

Platform-Specific Behavior

Specificity rules work consistently across platforms and variants:
Result on all platforms: Purple background because inline style always wins.

Best Practices

Use className for static styles and inline styles only for truly dynamic values that can’t be represented as classes, such as API values or animation interpolations.
Use cn from tailwind-merge when building component libraries to ensure predictable className overrides.
Avoid mixing className and inline styles for the same property. Choose one approach for consistency and maintainability.