Conditional class names
📚 What are Conditional Class Names? Conditional class names let you apply different CSS classes based on component state or props. This is how you make buttons look active, inputs show errors, or cards highlight on hover -- without inline styles. The pattern is: build a string of class names, addi…

Appy Says…
Active tab, selected button, error state, disabled input — these all involve toggling CSS classes based on state. React's JSX handles this with template literals, ternaries, and libraries like clsx.
What is Conditional className?
In React, className (not class) takes a string. You build that string dynamically using JavaScript — ternaries, template literals, or helper utilities.
- •
className={isActive ? 'btn active' : 'btn'} - •Template literal:
className={`btn ${isActive ? 'active' : ''}`} - •
clsxlibrary:className={clsx('btn', { active: isActive, disabled: isLoading })} - •
cn()utility (shadcn):className={cn('btn', isActive && 'active')} - •falsy values (false, null, undefined) in class strings are ignored by clsx/cn
- •Multiple conditions:
clsx('base', variant === 'primary' && 'bg-blue', size === 'sm' && 'text-sm')
Think of it like equipping armour sets in Minecraft
Your character has a base appearance, but switches to different armour sets based on game state (health, level, environment). Conditional classes do the same — base classes always on, additional classes toggled based on state.
How It Works
- •1. Start with base class(es) always applied
- •2. Add conditional classes using ternary or &&
- •3. Template literals are fine for 1–2 conditions
- •4. For 3+ conditions, install clsx:
npm install clsx - •5.
clsx('a', { b: true, c: false })→'a b' - •6. With Tailwind, use cn() (clsx + tailwind-merge) to avoid conflicting utility classes
Real-World Examples
- •Active nav link:
cn('nav-link', { 'font-bold underline': isActive }) - •Button states:
clsx('btn', variant, { 'opacity-50 cursor-not-allowed': disabled }) - •Form field error:
cn('input', errorMessage && 'border-red-500') - •Applaa track cards: active track gets a highlight ring via conditional class
Key Facts
- •clsx has 700M+ weekly npm downloads — it's the standard for conditional classes
- •tailwind-merge resolves Tailwind class conflicts (e.g. both 'p-2' and 'p-4' → keeps 'p-4')
- •In TypeScript: className={cn(...)} is fully typed via clsx's type definitions
- •CSS Modules work with conditional classes too:
styles[isActive ? 'active' : 'base']
Watch Out!
Avoid building large className strings with manual string concatenation — spaces are easy to miss and logic gets hard to read. Use clsx or cn() once you have more than 2 conditional classes. They're tiny utilities (1KB) with zero downsides.
Remember
className={cn('base', condition && 'extra', isError && 'error')}. Use clsx/cn for readable conditional classes. Falsy values are safely ignored.
What You Learned
- •Conditional className: ternary or clsx/cn to toggle CSS classes based on state
- •cn('base', condition && 'extra') — falsy values ignored; tailwind-merge resolves conflicts
- •Unlocks: active states, error highlighting, variant-based styling, any state-driven appearance
Key Facts
- →clsx has 700M+ weekly npm downloads — it's the standard for conditional classes
- →tailwind-merge resolves Tailwind class conflicts (e.g. both 'p-2' and 'p-4' → keeps 'p-4')
- →In TypeScript: className={cn(...)} is fully typed via clsx's type definitions
- →CSS Modules work with conditional classes too:
styles[isActive ? 'active' : 'base']
Real-World Examples
Remember
className={cn('base', condition && 'extra', isError && 'error')}. Use clsx/cn for readable conditional classes. Falsy values are safely ignored.
Quick Quiz
Conditional class is for?