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
// 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><!-- 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 staticclassattribute; it doesn't replace it. - Your notes mention
[ngClass]. It still works, but the Angular docs now recommend native[class]bindings.
Quick reference
| React | Angular |
|---|---|
className={`a ${cond ? 'b' : ''}`} | class="a" [class.b]="cond" |
clsx('a', { b: cond }) | [class]="{ b: cond }" (or [ngClass]) |