Product Card Variants — Compact, Default, Hero

Switch a product card between compact list-row, default grid-cell, and hero feature layouts based on container width using stacked @container rules in a single component.

Use Cases

Detailed Explanation

One Card, Three Personalities

E-commerce product cards typically need three variants: a tight list row in cart summaries, a standard grid card in catalog listings, and a hero card on the landing page. With container queries, one component covers all three.

The CSS

.product-host {
  container-type: inline-size;
  container-name: product;
}

/* Compact (list row) */
.product {
  display: grid;
  grid-template-columns: 60px 1fr auto;
  gap: 0.75rem;
  align-items: center;
}
.product img { aspect-ratio: 1; width: 60px; }
.product-description { display: none; }
.product-cta { font-size: 0.875rem; }

/* Default (grid card) */
@container product (min-width: 280px) {
  .product {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }
  .product img { aspect-ratio: 4/3; width: 100%; }
  .product-description {
    display: block;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }
}

/* Hero (feature card) */
@container product (min-width: 720px) {
  .product {
    grid-template-columns: 50% 1fr;
    gap: 2rem;
    align-items: center;
  }
  .product img { aspect-ratio: 4/3; }
  .product-description {
    -webkit-line-clamp: unset;
    font-size: 1.05rem;
  }
  .product-cta {
    font-size: 1.125rem;
    padding: 0.75rem 1.5rem;
  }
}

Three Sizes, One Markup

<!-- Same markup in all three contexts -->
<div class="product-host">
  <article class="product">
    <img src="…" alt="" />
    <div>
      <h3>Product name</h3>
      <p class="product-description">Long description…</p>
    </div>
    <button class="product-cta">Add to cart</button>
  </article>
</div>

Where Each Variant Lives

  • Compact: cart drawer, recently viewed list, "you may also like" sidebar
  • Default: search results, category listings (typically 220-380px hosts)
  • Hero: featured-product banners, comparison tables, landing-page sections

Avoiding Cumulative Layout Shift

Set a baseline aspect-ratio on the image element so the card reserves space before the image loads. The container query updates the ratio at each breakpoint, but the browser still has a stable initial layout.

Use Case

Use this pattern for e-commerce product cards, course catalogs, real-estate listings, recipe cards, and any catalog item that appears across feature banners, grid listings, and compact summary lists.

Try It — CSS Container Query Builder

Open full tool