Luciano Battagliero

Dynamic Styling in Tailwind

Published on

Tailwind generates CSS at build time. Class names must be statically analyzable, which means anything that depends on runtime values is outside of the compiler’s reach.

This is why expressions like h-[${height}] don’t work in Tailwind.

Once this constraint is clear, most dynamic styling problems fall into two categories:

  • Switching between known styles
  • Injecting new values at runtime

Conditional Class Selection

The simplest case is choosing between predefined classes. Using ternaries or helpers like cn works as long as all possible class names are known ahead of time.

<div
  className={cn({
    'w-16': !expanded,
    'w-64': expanded,
  })}
/>

Attribute-Derived Styling

When styling depends on component state, it’s usually better to reflect that state directly in the DOM. ARIA attributes likearia-expanded and custom data-* attributes can represent the current component state. Styles derive from those attributes instead of duplicating the same conditions inclassName.

<div
  aria-expanded={expanded}
  className="w-16 aria-expanded:w-64"
/>
Related Article: Attribute-Derived Styling.

Passing Runtime Values with CSS Variables

Widths, offsets, or other values that are only known at runtime cannot be encoded into Tailwind classes. CSS variables are the only way to pass those values through while keeping the class name static.

<div
  style={{ '--panel-width': ${width}px }}
  className="w-[var(--panel-width)]"
/>

Filed under #technical

Subscribe to the RSS feed