Alex Vipond
SHIFT + D

Wrap text around dismiss buttons on clickable cards

Published 4 days ago

Let's do something that sounds easy, but is tricky to get right: wrap text around the Dismiss button of a clickable card.

I'm baby mixtape jawn post-ironic jean shorts, cardigan VHS same austin roof party salvia master cleanse tofu etsy enamel pin.

(Open on Tailwind Play)

<!--
  Use role=group + aria-label to properly announce relationships
  between child elements. Add the relative class so we can 
  position the clickable action button absolutely.

  Bonus: set up a CSS variable to keep the card's border radius
  in sync with its clickable action button's border radius.
-->
<div
  role="group"
  aria-label="My group"
  class="
    isolate max-w-lg relative p-6
    bg-white shadow-md ring-1 ring-gray-900/5
    [--card-radius:theme(borderRadius.xl)]
    rounded-[var(--card-radius)]
  "
>
  <!--
    Render the action button first, so that it's first in the
    tab order. Position it absolutely to make the entire card
    clickable, and to draw a focus ring around the card. Use
    aria-labelledby to provide proper labeling.
  -->
  <button
    class="
      absolute inset-0
      rounded-[var(--card-radius)]
      focus-visible:outline-2
      focus-visible:outline-offset-2
      focus-visible:outline-blue-50
    "
    aria-labelledby="action-button-label"
    onclick="alert('Card clicked')"
  ></button>
  <!--
    Render the dismiss button next, so it can be floated to the
    right, which allows text wrapping. Add relative to stack it
    on top of the action button. Implement a focus ring.
  -->
  <button
    class="
      relative float-right
      rounded-full
      focus-visible:outline-2
      focus-visible:outline-offset-2
      focus-visible:outline-blue-50
      hover:bg-black/5
    "
    aria-label="Dismiss this card"
    onclick="alert('Card dismissed')"
  >
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.72 5.72a.75.75 0 0 1 1.06 0L12 10.94l5.22-5.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L13.06 12l5.22 5.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L12 13.06l-5.22 5.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.94 12 5.72 6.78a.75.75 0 0 1 0-1.06Z"></path></svg>
  </button>
  <!--
    Render wrapped text in a separate span, for two reasons:
    1. Text doesn't wrap properly around button elements, even
       when they have display:inline.
    2. We need to render our button first for the correct tab
       order, but the wrapped text needs to render after the
       dismiss button so that CSS float works properly.
    
    Match the span's id with the button's aria-labelledby to
    provide proper labeling.
  -->
  <span id="action-button-label">
    I'm baby mixtape jawn post-ironic jean shorts, cardigan VHS same austin roof party salvia master cleanse tofu etsy enamel pin.
  </span>
</div>

ON THIS PAGE

Wrap text around dismiss buttons on clickable cards