Conditionally Add Tailwind Classes With Data Attributes

Oct 17, 2024

Understanding data-attributes

data-attributes allow us to store extra information on HTML elements. This information can then be accessed via JavaScript or CSS.

Here's a basic example of a data attribute:

<button data-state="active">Click Me</button>

While data-attributes are traditionally used with JavaScript for DOM manipulation, Tailwind CSS enables us to style elements based on data-attributes, simplifying the process and improving maintainability.

Instead of conditionally adding Tailwind classes like this:

function Button({ state }) {
  return (
    <button
      className={state.active ? "opacity-100": "opacity-50"}
    >
      Button
    </button>
  )
}

Or like this:

function Button({ state }) {
  return (
    <button
      className={clsx({"opacity-100": state.active, "opacity-50": !state.active})}
    >
      Button
    </button>
  )
}

You can achieve the same effect using data-attributes for a more Tailwind like experience.

Code Playground
import { useState } from "react"

export default function App() {
  const [state, setState] = useState(true);
  
  const toggle = () => {
    setState(prev => !prev);
  };

  return (
    <div className="p-4 w-full h-screen text-white">
      <p>Current state: {state ? "active" : "disabled"}</p>
      <button 
        data-state={state ? "active" : "disabled"}
        onClick={toggle} 
        className="
          data-[state=active]:bg-opacity-100 
          data-[state=disabled]:opacity-50 
          p-2 bg-purple-500 rounded"
        >Click here
      </button>
    </div>
  )
}