1
0
mirror of https://github.com/jbranchaud/til synced 2026-01-03 15:18:01 +00:00
Files
til/tailwind/disable-and-enable-a-button.md
2025-09-29 18:54:05 -05:00

2.4 KiB

Disable And Enable A Button

With TailwindCSS we can take a couple different approaches to tie the visual and functional interactivity of a button to another elements state using classes.

One approach is to use peer and peer-checked:<class>.

<div>
  <input
    type="checkbox"
    id="peer-enable"
    class="w-5 h-5 cursor-pointer peer"
  />
  <label
    for="peer-enable"
    class="cursor-pointer text-slate-700 font-medium"
  >
    I agree to the terms and conditions
  </label>
  <button
    class="opacity-40 pointer-events-none grayscale cursor-not-allowed peer-checked:opacity-100 peer-checked:pointer-events-auto peer-checked:grayscale-0 peer-checked:cursor-pointer"
  >
    Peer Submit
  </button>
</div>

Classes to make to button appear disabled (e.g. opacity-40) as well as functional classes that affect interactivity (e.g. pointer-events-none) are applied by default. When the sibling checkbox gets checked, the inverted classes take effect making the button enabled.

The peer approach works, but lacks flexibility. As soon as I need to make any structural changes to the HTML that sever the peer (i.e. sibling) relationship of the checkbox and the button, those classes stop working.

With group and group-has-[:checked]:<class>, I can style the button relative to another group member as long as everything is nested under some shared group tag.

<div class="group">
  <div class="flex items-center gap-3">
    <input
      type="checkbox"
      id="group-enable"
      class="w-5 h-5 cursor-pointer"
    />
    <label
      for="group-enable"
      class="cursor-pointer text-slate-700 font-medium"
    >
      I agree to the terms and conditions
    </label>
  </div>
  <button
    class="opacity-40 pointer-events-none grayscale cursor-not-allowed group-has-[:checked]:opacity-100 group-has-[:checked]:pointer-events-auto group-has-[:checked]:grayscale-0 group-has-[:checked]:cursor-pointer"
  >
    Group Submit
  </button>
</div>

We can even utilize named groups if we have overlapping and conflicting group interactions. But I won't get into that here.