Styling React ComponentsEntry 3 of 7

Conditional (Dynamic) Classes

Adding or removing CSS classes based on state.

Notes

className is just a string, so you build it with JavaScript. A template literal combines static and conditional classes. For more than one or two conditions, the small clsx library keeps it readable.

Prefer conditional classes over conditional inline styles: the styling stays in CSS, where hover states and media queries work.

What / Why / When

What

State-driven class names.

Why

Keeps visual rules in CSS while the component only decides which rules apply.

When

Validation errors, active tabs, selected items, disabled states.

Use case

Turning an email label red when the email is invalid.

Code compare

React
// Template literal (from the course)<label className={`label ${emailNotValid ? 'invalid' : ''}`}>Email</label>​// Single conditional class: pass undefined so no empty class attribute is rendered<label className={emailNotValid ? 'invalid' : undefined}>Email</label>​// Several conditions: clsx (npm install clsx)import clsx from 'clsx';​<label className={clsx('label', { invalid: emailNotValid, required: isRequired })}>  Email</label>
Angular
<!-- Single class --><label class="label" [class.invalid]="emailNotValid()">Email</label>​<!-- Several classes --><label class="label" [class]="{ invalid: emailNotValid(), required: isRequired() }"> Email </label>

Differences and gotchas

  • Angular's [class.name] binding is built in, so there's no string building and no library needed.
  • In Angular, a [class] binding merges with the static class attribute; it doesn't replace it.
  • Your notes mention [ngClass]. It still works, but the Angular docs now recommend native [class] bindings.

Quick reference

ReactAngular
className={`a ${cond ? 'b' : ''}`}class="a" [class.b]="cond"
clsx('a', { b: cond })[class]="{ b: cond }" (or [ngClass])