When you add a disabled attribute to a <button> element, you probably expect it to just... look disabled. But there's a subtle trap that catches a lot of developers: your hover: styles still apply visually, even when the button is disabled.
The problem
Consider a typical Tailwind button:
<button class="bg-gray-200 hover:bg-gray-300 hover:cursor-pointer" disabled>
Click me
</button>
Even though the button is disabled and won't fire any events, the hover:bg-gray-300 and hover:cursor-pointer classes still apply on hover. The cursor becomes a pointer and the background changes — giving the user a false signal that the button is interactive.
The fix: enabled:
Tailwind ships with an enabled: variant that maps directly to the CSS :enabled pseudo-class. Swap your hover: styles for enabled:hover: and the problem disappears:
<button class="bg-gray-200 enabled:hover:bg-gray-300 enabled:hover:cursor-pointer" disabled>
Click me
</button>
Now those styles only apply when the button is not disabled. No JavaScript, no conditional class logic, no extra wrapper — just a single variant prefix.
Why this matters
The :enabled pseudo-class is the semantic opposite of :disabled. It's supported in all modern browsers and has been in CSS for years, but it's easy to overlook because disabled states are often handled with opacity or a wrapper div instead.
Using enabled:hover: keeps your intent explicit in the markup and makes disabled state handling a one-liner in your component library.
In practice (Phoenix / LiveView)
If you have a reusable button component, this is the ideal place to apply it. Instead of:
"hover:bg-gray-300 hover:cursor-pointer"
Write:
"enabled:hover:bg-gray-300 enabled:hover:cursor-pointer"
Now any caller that passes disabled as an attribute gets correct visual behavior automatically — no special-case classes needed at the call site.
Small trick, but it saves a prop, a conditional, and a subtle UX bug all at once.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.