← Back to Chapters

Conditional Class Names

⚛️ Conditional Class Names

? Quick Overview

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

? Key Concepts

  • Conditional class name: A CSS class applied only when some condition is true.
  • Ternary operator: Simple inline condition ? "class-a" : "class-b" logic.
  • Template literals: Combine static and dynamic classes in a single backtick string.
  • Helper function: Encapsulates complex logic to return the right class string.
  • classnames library: Popular package for clean, declarative class toggling.

? Syntax & Theory

In React, you don’t use the HTML class attribute. Instead, you use className and pass it a JavaScript expression:

  • Inline ternary: className={isActive ? "btn btn-success" : "btn btn-secondary"}
  • Template literal: {`base-class ${condition ? "extra-class" : ""}`}
  • Function: 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).

? Using Ternary Operator

The simplest way to apply conditional classes is with the ternary operator directly inside className.

? View Code Example
// 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>
  );
}

? Explanation / Output

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

? Using Template Literals

Template literals are perfect when you need a base set of classes plus extra ones that depend on state.

? View Code Example
// 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>
  );
}

? Explanation / Output

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.

? Multiple Conditional Classes with Helper Function

For more complex logic, it’s cleaner to move the class selection into a separate function.

? View Code Example
// 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>
  );
}

? Explanation / Output

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.

⚙️ Using the classnames Library

The classnames package makes complex conditional class logic more readable and scalable, especially in larger apps.

? View Code Example
// 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>
  );
}

? Explanation / Output

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.

? Comparison of Methods

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

? Tips & Best Practices

  • Keep base classes (like layout or spacing) static; toggle only what’s necessary (e.g., color or state styles).
  • Use classnames or helper functions when the inline ternary becomes long or hard to read.
  • Remember that className replaces all existing classes—it doesn’t merge them automatically for you.
  • For CSS Modules or Tailwind, you can still combine them with template literals or classnames for clarity.
  • Prefer descriptive state names like status, variant, or intent to make class logic self-explanatory.

? Try It Yourself / Practice Tasks

  1. Create a button that changes color and label dynamically between “Start”, “Stop”, and “Reset” using a helper function.
  2. Build a login form that shows success, warning, or error messages with different alert classes based on validation result.
  3. Install classnames and use it to toggle dark and light themes on a simple card or page layout.
  4. Inspect element classes in DevTools and watch how the 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.