Conditional class names let you apply CSS classes dynamically based on React component state or props. This is one of the most common techniques to control how elements look and behave in real time.
You can use JavaScript expressions like the ? ternary operator, template literals, helper functions, or utility libraries such as classnames to manage multiple conditional styles cleanly.
⚛️ React UI Styling ? Dynamic Classes ? State-based UI
condition ? "class-a" : "class-b" logic.classnames library: Popular package for clean, declarative class toggling.In React, you don’t use the HTML class attribute. Instead, you use className and pass it a JavaScript expression:
className={isActive ? "btn btn-success" : "btn btn-secondary"}{`base-class ${condition ? "extra-class" : ""}`}className={getClassName(status)}classnames: className={classNames("btn", { active, disabled })}Remember: className sets the entire class string for an element—so you typically combine base classes (always present) with conditional classes (added or removed based on logic).
The simplest way to apply conditional classes is with the ternary operator directly inside className.
// Toggle button style based on active state
function TernaryExample() {
const [active, setActive] = React.useState(false);
return (
<div className="text-center mt-3">
<button
className={active ? "btn btn-success" : "btn btn-secondary"}
onClick={() => setActive(!active)}
>
{active ? "Active" : "Inactive"}
</button>
</div>
);
}
The button starts in the Inactive state with the btn-secondary class. When you click it, active flips to true, the label changes to Active, and the class switches to btn-success.
Use this pattern when you have a simple either/or visual change (e.g., on/off, active/inactive, show/hide).
Template literals are perfect when you need a base set of classes plus extra ones that depend on state.
// Combine static and dynamic classes with template literals
function TemplateLiteralExample() {
const [dark, setDark] = React.useState(false);
return (
<div className={`p-3 text-center ${dark ? "bg-dark text-light" : "bg-light text-dark"}`}>
<h5>{dark ? "Dark Mode" : "Light Mode"}</h5>
<button
className="btn btn-outline-primary"
onClick={() => setDark(!dark)}
>
Toggle Mode
</button>
</div>
);
}
The p-3 text-center classes are always applied, while the background and text color classes change based on dark. This is great for small theme toggles or layout + color combinations.
For more complex logic, it’s cleaner to move the class selection into a separate function.
// Return different alert classes based on status value
function MultiClassExample() {
const [status, setStatus] = React.useState("idle");
const getClass = () => {
if (status === "success") return "alert alert-success";
if (status === "error") return "alert alert-danger";
return "alert alert-warning";
};
return (
<div className="text-center">
<div className={getClass()}>Status: {status}</div>
<div className="btn-group">
<button
className="btn btn-success"
onClick={() => setStatus("success")}
>
Success
</button>
<button
className="btn btn-danger"
onClick={() => setStatus("error")}
>
Error
</button>
<button
className="btn btn-warning"
onClick={() => setStatus("idle")}
>
Idle
</button>
</div>
</div>
);
}
Depending on which button you click, the alert box will change its label and class: alert-success, alert-danger, or alert-warning.
This pattern is ideal for dashboards, notification centers, and anywhere you have several visual states driven by one value.
classnames LibraryThe classnames package makes complex conditional class logic more readable and scalable, especially in larger apps.
// Use the classnames package to manage multiple toggles
// 1️⃣ Install classnames (run in terminal)
npm install classnames
// 2️⃣ React component using classnames
import React, { useState } from "react";
import classNames from "classnames";
import "./Button.css";
function ClassNamesExample() {
const [active, setActive] = useState(false);
const [disabled, setDisabled] = useState(false);
const btnClass = classNames("btn", {
"btn-primary": active,
"btn-secondary": !active,
disabled: disabled
});
return (
<div className="text-center">
<button
className={btnClass}
disabled={disabled}
onClick={() => setActive(!active)}
>
{active ? "Active" : "Inactive"}
</button>
<br />
<button
className="btn btn-outline-dark mt-2"
onClick={() => setDisabled(!disabled)}
>
Toggle Disabled
</button>
</div>
);
}
The btnClass variable always includes the base btn class, and then adds btn-primary, btn-secondary, and disabled depending on the current state values.
The object syntax inside classNames() is declarative and easy to scan: keys are class names, and values are the conditions that must be true to include them.
| Method | Syntax | Best For |
|---|---|---|
| Ternary Operator | Inline condition ? A : B |
Simple two-way toggles |
| Template Literals | Backtick strings with placeholders | Base + dynamic extra classes |
| Functions | Return class based on logic | Complex decision trees |
| classnames Library | Declarative object/array syntax | Large apps with many toggles |
classnames or helper functions when the inline ternary becomes long or hard to read.className replaces all existing classes—it doesn’t merge them automatically for you.classnames for clarity.status, variant, or intent to make class logic self-explanatory.classnames and use it to toggle dark and light themes on a simple card or page layout.class attribute updates as you interact with the UI.Goal: Become comfortable applying class names conditionally in React using ternary operators, template literals, helper functions, and the classnames library to build dynamic, responsive UIs.