Snippets Animation

Bootstrap 5 Product Card with Colour Swatches

A product card with a large photo, wishlist toggle, rating, sale price, colour swatches, quantity stepper and an add-to-cart button.

Bootstrap 5 No jQuery Feb 2020 2.1K views

<section class="wdw-stage">
  <div class="container" style="max-width:880px">
    <article class="wdw-card overflow-hidden product">
      <div class="row g-0">
        <div class="col-md-6 product-media position-relative">
          <img src="https://images.unsplash.com/photo-1546435770-a3e426bf472b?auto=format&fit=crop&w=900&q=75" alt="Black over-ear headphones on a white desk" data-product-image>
          <span class="badge rounded-pill text-bg-light position-absolute top-0 start-0 m-3 px-3 py-2">New</span>
          <button type="button" class="btn rounded-circle position-absolute top-0 end-0 m-3 p-0 fav" aria-label="Save to wishlist" aria-pressed="false">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7-4.4-9-9.2C1.8 7.6 3.8 4.5 7 4.5c2 0 3.3 1 5 3 1.7-2 3-3 5-3 3.2 0 5.2 3.1 4 6.3-2 4.8-9 9.2-9 9.2Z"/></svg>
          </button>
        </div>
        <div class="col-md-6 p-4 p-lg-5 d-flex flex-column">
          <div class="d-flex justify-content-between align-items-start gap-3 mb-2">
            <span class="wdw-eyebrow">Audio</span>
            <span class="d-inline-flex align-items-center gap-1 small fw-semibold">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="#f59e0b" aria-hidden="true"><path d="m12 2.5 2.9 6 6.6.9-4.8 4.6 1.2 6.5L12 17.3 6.1 20.5l1.2-6.5L2.5 9.4l6.6-.9L12 2.5Z"/></svg>
              <span class="visually-hidden">Rated 4.8 out of 5 from 214 reviews</span>
              <span aria-hidden="true">4.8 <span class="wdw-muted fw-normal">(214)</span></span>
            </span>
          </div>
          <h2 class="wdw-heading h3 mb-1">Aero ANC Headphones</h2>
          <p class="wdw-muted mb-3">Active noise cancelling, 40-hour battery and a folding hard case.</p>
          <p class="mb-4"><span class="h2 fw-bold me-2" data-price>$220</span><s class="wdw-muted">$269</s> <span class="badge rounded-pill bg-success text-white ms-1">Save 18%</span></p>

          <fieldset class="mb-4">
            <legend class="small fw-bold text-uppercase wdw-muted mb-2" style="font-size:.75rem;letter-spacing:.06em">Colour: <span class="text-body-emphasis" data-colour-name>Graphite</span></legend>
            <div class="d-flex gap-2">
              <input type="radio" class="btn-check" name="colour" id="c1" value="Graphite" data-src="https://images.unsplash.com/photo-1546435770-a3e426bf472b?auto=format&fit=crop&w=900&q=75" data-alt="Black over-ear headphones on a white desk" checked><label class="swatch" for="c1" style="--c:#1f2937;--ck:#fff"><span class="visually-hidden">Graphite</span></label>
              <input type="radio" class="btn-check" name="colour" id="c2" value="Sand" data-src="https://images.unsplash.com/photo-1618366712010-f4ae9c647dcb?auto=format&fit=crop&w=900&q=75" data-alt="Dark over-ear headphones on a warm sand backdrop"><label class="swatch" for="c2" style="--c:#d6c7a8;--ck:#3b3322"><span class="visually-hidden">Sand</span></label>
              <input type="radio" class="btn-check" name="colour" id="c3" value="Rose" data-src="https://images.unsplash.com/photo-1524678606370-a47ad25cb82a?auto=format&fit=crop&w=900&q=75" data-alt="Pink headphones against rose and mint panels"><label class="swatch" for="c3" style="--c:#d8a7a7;--ck:#5a2a2a"><span class="visually-hidden">Rose</span></label>
              <input type="radio" class="btn-check" name="colour" id="c4" value="Lilac" data-src="https://images.unsplash.com/photo-1577174881658-0f30ed549adc?auto=format&fit=crop&w=900&q=75" data-alt="White headphones on a lilac backdrop"><label class="swatch" for="c4" style="--c:#a5b4fc;--ck:#1e1b4b"><span class="visually-hidden">Lilac</span></label>
            </div>
          </fieldset>

          <div class="d-flex gap-2 mt-auto">
            <div class="input-group qty" style="width:9rem">
              <button class="btn btn-outline-secondary" type="button" data-qty="-1" aria-label="Decrease quantity"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/></svg></button>
              <input class="form-control text-center px-0" type="number" min="1" max="10" value="1" aria-label="Quantity" data-qty-input>
              <button class="btn btn-outline-secondary" type="button" data-qty="1" aria-label="Increase quantity"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M12 5v14"/></svg></button>
            </div>
            <button type="button" class="btn btn-primary rounded-pill flex-grow-1" data-add><svg class="ck-icon d-none" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12.5 4.5 4.5L19 7.5"/></svg><span data-add-label>Add to cart</span></button>
          </div>
          <p class="small text-center wdw-muted mt-3 mb-0" role="status" data-cart-status>Free shipping over $100</p>
        </div>
      </div>
    </article>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.