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.
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.