Luciano Battagliero

§Dynamic Styling in Tailwind

Published on

Tailwind generates CSS at build time, so class names can’t be dynamically constructed. Any class name that doesn’t exist as a literal string will be ignored by the compiler.

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, or 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)]"
/>

The constraint is always the same: Tailwind needs static class names. These are simple ways to work within that boundary instead of around it.

Filed under #technical

Subscribe to the RSS feed