§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.