Skip to content

Product Card with Color Options

Tailwind CSS product card with live-recoloring color swatches, a size selector with sold-out state, wishlist toggle and add to bag button.

Live preview

Open in new tab

Code

A Tailwind CSS product card with clickable color swatches, a size selector and an "Add to bag" button, built for e-commerce listings, quick-view panels and single-product landing pages. The illustrated backpack recolors itself live when a shopper picks a color, so the card shows exactly what they are about to buy.

How it works

The root is .tpv-card, an article labelled by the product name. The top area, .tpv-stage, holds an inline SVG (.tpv-product) whose main shapes use fill="currentColor". In style.css the SVG color and the tinted stage background both read the --tpv-color custom property, mixed with white through color-mix().

Colors are a fieldset of native radio buttons visually hidden with sr-only; each one carries its hex value in data-tpv-color. The visible circle is a sibling span styled with peer-checked: and peer-focus-visible: utilities, so selection and focus rings work without JavaScript. Sizes use the same pattern as rounded buttons; the sold-out XL radio is disabled and its label gets the diagonal strike from .tpv-soldout.

script.js initializes every .tpv-card on DOMContentLoaded. A change listener on the color radios writes the new value to --tpv-color, updates the data-tpv-color-name label and the SVG title. Clicking data-tpv-add checks for a chosen size: without one it reveals the data-tpv-error message and moves focus to the first available size; otherwise it writes a confirmation into the data-tpv-status region. The heart button (data-tpv-fav) flips aria-pressed, which the aria-pressed: and group-aria-pressed: variants use to fill the icon red.

Customization

  • --tpv-color on .tpv-card in style.css: sets the default product color before the script runs; keep it in sync with the checked swatch.
  • data-tpv-color and value on each color radio: change the hex code and name; also update the matching bg-[#c2410c] utility on the swatch circle.
  • Add disabled to any size radio and swap its span for the .tpv-soldout styling to mark it unavailable.
  • grid-cols-4 on the size grid: use grid-cols-5 or grid-cols-3 to match your number of sizes.
  • rounded-[2rem] and max-w-sm on .tpv-card: change the corner radius or make the card wider.
  • Replace the SVG inside .tpv-stage with your own artwork that uses currentColor, or with an img if you do not need live recoloring.

Accessibility

Both option groups are real radio buttons inside fieldset elements with a legend, so arrow keys move between options and screen readers announce the group and the selected value. Each swatch has a visually hidden color name, the sold-out size says "(sold out)", and the product SVG has role="img" with a title that follows the chosen color. The error uses role="alert", results are announced through role="status", and every control has a visible amber focus outline. Hover and color transitions are disabled under prefers-reduced-motion: reduce.

Usage notes

For several cards on one page, give each card unique radio name values (for example tpv-color-2) and unique id values for the heading and SVG title; the script already scopes everything to its own .tpv-card.

Requirements

Add these to your page (already included in the download):

  • <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

The Tailwind browser build is for prototyping. In production, compile Tailwind with its CLI or your bundler.

Product Card with Color Options – Tailwind CSS product cards component screenshot
Product Card with Color Options · Tailwind CSS Product Cards

More Product Cards

Product Card with Quick Actions – Pure CSS product cards preview

Product Card with Quick Actions

Responsive product card grid where hover or focus reveals wishlist, quick view and add-to-cart actions, with star ratings and a native quick view dialog.