DEV3 Technologies home

Product card with quick add

A product card with an image, price, rating and an add-to-cart button that reveals on hover and always shows on touch.

Tailwind CSSCardsproductcardecommercehover

Live preview

Code

<article class="group relative w-64 overflow-hidden rounded-xl border border-slate-200 bg-white">
  <a href="/products/linen-shirt" class="block">
    <div class="relative aspect-[4/5] overflow-hidden bg-slate-100">
      <img src="/img/linen-shirt.jpg" alt="Linen shirt in sand colour" loading="lazy"
        class="size-full object-cover transition-transform duration-300 group-hover:scale-105">
    </div>
    <div class="p-4">
      <h3 class="truncate text-sm font-medium text-slate-900">Linen shirt</h3>
      <p class="mt-1 flex items-center justify-between text-sm">
        <span class="font-semibold text-slate-900">$54.00</span>
        <span class="text-amber-500" aria-label="Rated 4.5 out of 5">&#9733;&#9733;&#9733;&#9733;&#9734;</span>
      </p>
    </div>
  </a>

  <!-- hidden until hover or focus; always visible on touch -->
  <button type="button" data-sku="SHIRT-001"
    class="absolute inset-x-3 top-[calc(100%-5rem)] translate-y-24 rounded-lg bg-slate-900 py-2 text-sm font-semibold text-white opacity-0 transition
           group-hover:translate-y-0 group-hover:opacity-100 group-focus-within:translate-y-0 group-focus-within:opacity-100
           pointer-coarse:static pointer-coarse:m-3 pointer-coarse:w-[calc(100%-1.5rem)] pointer-coarse:translate-y-0 pointer-coarse:opacity-100">
    Add to cart
  </button>
  <span class="sr-only" role="status" data-added-note></span>
</article>

How it works

What it solves

Shop listing grids need a fast way to add an item without opening the product page, but hover-only buttons are unreachable on phones and for keyboard users. This card reveals the action on hover and focus and keeps it visible on touch screens.

How it works

The card is an article with a group class. The image wrapper has a fixed aspect-[4/5] ratio so layout does not shift while pictures load. The quick-add button sits at the bottom of the image, translated out of view with translate-y-full and moved in by group-hover:translate-y-0 and group-focus-within:translate-y-0; the focus-within variant is what makes keyboard use work. A pointer-coarse:translate-y-0 variant keeps the button visible on touch devices. The script finds buttons by a data-sku attribute, posts nothing itself, and dispatches a custom cart:add event so your cart code can listen. It also updates the label to "Added" briefly and announces it through a status span.

Adapting it

Listen for cart:add on document and call your API. For variants, replace the button with a link to the product page when options are required. Show a sale badge with an absolutely positioned span.

Pitfalls

  • Never disable the product link inside the card; the image stays clickable.
  • Hover-only controls fail on touch; always provide the coarse pointer rule.
  • Debounce repeated clicks if your cart call is slow.

How to use it

  1. Paste product-card.html inside a grid, repeating it per product with a unique data-sku.
  2. Load quick-add.js with defer.
  3. Listen for the cart:add event on document and call your own cart endpoint.
  4. Swap the inline image for your own source and keep the aspect ratio wrapper.

Licence: DEV3 Snippet Licence. Free to use, change and ship in personal and commercial projects. Attribution is appreciated, not required. Please do not redistribute snippets as a collection.

Related snippets