Conditional Styling in Tailwind with Next.js

2024-01-09
By: O. Wolfson

Next.js, combined with Tailwind CSS, offers a powerful platform for building dynamic and visually appealing web applications. In this article, we'll explore how to use conditional styling in Tailwind within a Next.js application. We'll create a server component for the main page and use client components for interactive parts, focusing on a "status indicator" example.

Prerequisites

  • Basic understanding of React and Next.js.
  • Familiarity with Tailwind CSS.
  • Next.js and Tailwind CSS set up in your development environment.

pages/index.js

jsx
import DynamicTest from "../components/DynamicTest";

export default function Home() {
  return (
    <div>
      <h1 className="text-2xl font-bold">conditional styling Example</h1>
      <DynamicTest />
    </div>
  );
}

The DynamicTest component demonstrates conditional styling using Tailwind CSS. We'll explore two techniques: using clsx and ternary expressions within template literals.

components/DynamicTest.js

jsx
"use client";
import React, { useState } from "react";
import clsx from "clsx";

function DynamicTest() {
  const [simpleStatus, setSimpleStatus] = useState(false); // Binary state for ternary example
  const [complexStatus, setComplexStatus] = useState("none"); // Multi-state for clsx example

  return (
    <div>
      {/* Ternary Expressions for Binary Condition */}
      <div
        className={`mt-2 inline-flex items-center rounded-full px-2 py-1 text-sm ${
          simpleStatus ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-500"
        }`}
      >
        Using Ternary: {simpleStatus ? "Active" : "Inactive"}
      </div>
      <button
        className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
        onClick={() => setSimpleStatus(!simpleStatus)}
      >
        Toggle Simple Status
      </button>

      {/* clsx for Multiple Conditions */}
      <div
        className={clsx(
          "mt-4 inline-flex items-center rounded-full px-2 py-1 text-sm",
          {
            "bg-red-500 text-white": complexStatus === "error",
            "bg-yellow-500 text-black": complexStatus === "warning",
            "bg-green-500 text-white": complexStatus === "success",
            "bg-gray-100 text-gray-500": complexStatus === "none",
          }
        )}
      >
        Using clsx:{" "}
        {complexStatus.charAt(0).toUpperCase() + complexStatus.slice(1)}
      </div>
      <div className="mt-4 space-x-2">
        <button
          className="px-4 py-2 bg-red-500 text-white rounded"
          onClick={() => setComplexStatus("error")}
        >
          Set Error
        </button>
        <button
          className="px-4 py-2 bg-yellow-500 text-black rounded"
          onClick={() => setComplexStatus("warning")}
        >
          Set Warning
        </button>
        <button
          className="px-4 py-2 bg-green-500 text-white rounded"
          onClick={() => setComplexStatus("success")}
        >
          Set Success
        </button>
        <button
          className="px-4 py-2 bg-gray-500 text-white rounded"
          onClick={() => setComplexStatus("none")}
        >
          Clear Status
        </button>
      </div>
    </div>
  );
}

export default DynamicTest;

Explanation:

  • Using clsx: The clsx library is used to conditionally apply classes. It's useful when there are multiple classes that need to be toggled based on a condition.
  • Using Ternary Expressions in Template Literals: This technique is straightforward and great for simpler conditional logic. It's particularly useful when toggling between two classes.

Conclusion

The DynamicTest component showcased two techniques for conditional class rendering: using clsx and ternary expressions within template literals. The choice between the two largely depends on the complexity of your styling conditions and personal or team preferences. For simple, binary conditions, ternary expressions are typically sufficient and more straightforward. For more complex scenarios with multiple conditions and class variations, clsx offers a more readable and manageable approach.