18 CSS Product Cards11 / 18
Horizontal Responsive Card
A horizontal image-left / details-right card for cart pages, comparison rows and mobile search listings — that automatically stacks to vertical when its container gets narrow, using a container query rather than a viewport media query.
Published
The code
<div class="cpc-11">
<article class="cpc-11__wrap">
<div class="cpc-11__card">
<div class="cpc-11__img" role="img" aria-label="Product photo: Ridge insulated bottle"><span>product shot</span></div>
<div class="cpc-11__body">
<div><h3 class="cpc-11__name">Ridge Insulated Bottle · 750ml</h3><p class="cpc-11__meta">Slate · Keeps cold 24h</p></div>
<div class="cpc-11__foot">
<p class="cpc-11__price">$35</p>
<div class="cpc-11__actions">
<button type="button" class="cpc-11__ghost">Save</button>
<button type="button" class="cpc-11__cta">Add to Cart</button>
</div>
</div>
</div>
</div>
</article>
</div><div class="cpc-11">
<article class="cpc-11__wrap">
<div class="cpc-11__card">
<div class="cpc-11__img" role="img" aria-label="Product photo: Ridge insulated bottle"><span>product shot</span></div>
<div class="cpc-11__body">
<div><h3 class="cpc-11__name">Ridge Insulated Bottle · 750ml</h3><p class="cpc-11__meta">Slate · Keeps cold 24h</p></div>
<div class="cpc-11__foot">
<p class="cpc-11__price">$35</p>
<div class="cpc-11__actions">
<button type="button" class="cpc-11__ghost">Save</button>
<button type="button" class="cpc-11__cta">Add to Cart</button>
</div>
</div>
</div>
</div>
</article>
</div>.cpc-11,
.cpc-11 *,
.cpc-11 *::before,
.cpc-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cpc-11 ::selection {
background: oklch(0.6 0.13 230);
color: #fff;
}
.cpc-11 {
--accent: oklch(0.52 0.14 235);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 20px;
background: #eef1f5;
}
.cpc-11__wrap {
container-type: inline-size;
width: min(520px,100%);
}
.cpc-11__card {
display: flex;
gap: 0;
background: #fff;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 14px 36px -20px rgba(16,24,40,.4);
}
.cpc-11__img {
flex: 0 0 40%;
aspect-ratio: 1/1;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg,#dbe3ee,#c9d5e6),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 0 12px,transparent 12px 24px);
}
.cpc-11__img {
background-image: url("https://loremflickr.com/600/600/waterbottle?lock=21");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.cpc-11__img span {
display: none;
}
.cpc-11__body {
flex: 1;
padding: 20px 22px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
}
.cpc-11__name {
font-size: 17px;
font-weight: 600;
color: #101828;
line-height: 1.35;
}
.cpc-11__meta {
margin-top: 4px;
font-size: 13px;
color: #667085;
}
.cpc-11__foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.cpc-11__price {
font-size: 20px;
font-weight: 800;
color: #101828;
}
.cpc-11__actions {
display: flex;
gap: 8px;
}
.cpc-11__ghost {
height: 42px;
padding: 0 16px;
border: 1px solid #d0d5dd;
border-radius: 10px;
cursor: pointer;
background: #fff;
color: #344054;
font-size: 13px;
font-weight: 600;
}
.cpc-11__ghost:hover {
border-color: var(--accent);
color: var(--accent);
}
.cpc-11__cta {
height: 42px;
padding: 0 18px;
border: none;
border-radius: 10px;
cursor: pointer;
background: var(--accent);
color: #fff;
font-size: 13px;
font-weight: 600;
}
.cpc-11__cta:hover {
background: color-mix(in oklch,var(--accent) 88%,#000);
}
.cpc-11__ghost:focus-visible,
.cpc-11__cta:focus-visible {
outline: 3px solid color-mix(in oklch,var(--accent) 45%,#fff);
outline-offset: 2px;
}
@container (max-width: 420px) {
.cpc-11__card {
flex-direction: column;
}
.cpc-11__img {
flex: none;
width: 100%;
aspect-ratio: 16/9;
}
}
@media (prefers-reduced-motion: reduce) {
}.cpc-11,
.cpc-11 *,
.cpc-11 *::before,
.cpc-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cpc-11 ::selection {
background: oklch(0.6 0.13 230);
color: #fff;
}
.cpc-11 {
--accent: oklch(0.52 0.14 235);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 20px;
background: #eef1f5;
}
.cpc-11__wrap {
container-type: inline-size;
width: min(520px,100%);
}
.cpc-11__card {
display: flex;
gap: 0;
background: #fff;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 14px 36px -20px rgba(16,24,40,.4);
}
.cpc-11__img {
flex: 0 0 40%;
aspect-ratio: 1/1;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg,#dbe3ee,#c9d5e6),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 0 12px,transparent 12px 24px);
}
.cpc-11__img {
background-image: url("https://loremflickr.com/600/600/waterbottle?lock=21");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.cpc-11__img span {
display: none;
}
.cpc-11__body {
flex: 1;
padding: 20px 22px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
}
.cpc-11__name {
font-size: 17px;
font-weight: 600;
color: #101828;
line-height: 1.35;
}
.cpc-11__meta {
margin-top: 4px;
font-size: 13px;
color: #667085;
}
.cpc-11__foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.cpc-11__price {
font-size: 20px;
font-weight: 800;
color: #101828;
}
.cpc-11__actions {
display: flex;
gap: 8px;
}
.cpc-11__ghost {
height: 42px;
padding: 0 16px;
border: 1px solid #d0d5dd;
border-radius: 10px;
cursor: pointer;
background: #fff;
color: #344054;
font-size: 13px;
font-weight: 600;
}
.cpc-11__ghost:hover {
border-color: var(--accent);
color: var(--accent);
}
.cpc-11__cta {
height: 42px;
padding: 0 18px;
border: none;
border-radius: 10px;
cursor: pointer;
background: var(--accent);
color: #fff;
font-size: 13px;
font-weight: 600;
}
.cpc-11__cta:hover {
background: color-mix(in oklch,var(--accent) 88%,#000);
}
.cpc-11__ghost:focus-visible,
.cpc-11__cta:focus-visible {
outline: 3px solid color-mix(in oklch,var(--accent) 45%,#fff);
outline-offset: 2px;
}
@container (max-width: 420px) {
.cpc-11__card {
flex-direction: column;
}
.cpc-11__img {
flex: none;
width: 100%;
aspect-ratio: 16/9;
}
}
@media (prefers-reduced-motion: reduce) {
}/* No JavaScript — a @container query stacks the horizontal card when its wrapper narrows. */
/* No JavaScript — a @container query stacks the horizontal card when its wrapper narrows. */Here's a working CSS Product Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Horizontal Responsive Card
Source: https://codefronts.com/components/css-product-cards/horizontal-responsive-card/
A horizontal image-left / details-right card for cart pages, comparison rows and mobile search listings — that automatically stacks to vertical when its container gets narrow, using a container query rather than a viewport media query.
## HTML
```html
<div class="cpc-11">
<article class="cpc-11__wrap">
<div class="cpc-11__card">
<div class="cpc-11__img" role="img" aria-label="Product photo: Ridge insulated bottle"><span>product shot</span></div>
<div class="cpc-11__body">
<div><h3 class="cpc-11__name">Ridge Insulated Bottle · 750ml</h3><p class="cpc-11__meta">Slate · Keeps cold 24h</p></div>
<div class="cpc-11__foot">
<p class="cpc-11__price">$35</p>
<div class="cpc-11__actions">
<button type="button" class="cpc-11__ghost">Save</button>
<button type="button" class="cpc-11__cta">Add to Cart</button>
</div>
</div>
</div>
</div>
</article>
</div>
```
## CSS
```css
.cpc-11,
.cpc-11 *,
.cpc-11 *::before,
.cpc-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cpc-11 ::selection {
background: oklch(0.6 0.13 230);
color: #fff;
}
.cpc-11 {
--accent: oklch(0.52 0.14 235);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 20px;
background: #eef1f5;
}
.cpc-11__wrap {
container-type: inline-size;
width: min(520px,100%);
}
.cpc-11__card {
display: flex;
gap: 0;
background: #fff;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 14px 36px -20px rgba(16,24,40,.4);
}
.cpc-11__img {
flex: 0 0 40%;
aspect-ratio: 1/1;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg,#dbe3ee,#c9d5e6),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 0 12px,transparent 12px 24px);
}
.cpc-11__img {
background-image: url("https://loremflickr.com/600/600/waterbottle?lock=21");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.cpc-11__img span {
display: none;
}
.cpc-11__body {
flex: 1;
padding: 20px 22px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
}
.cpc-11__name {
font-size: 17px;
font-weight: 600;
color: #101828;
line-height: 1.35;
}
.cpc-11__meta {
margin-top: 4px;
font-size: 13px;
color: #667085;
}
.cpc-11__foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.cpc-11__price {
font-size: 20px;
font-weight: 800;
color: #101828;
}
.cpc-11__actions {
display: flex;
gap: 8px;
}
.cpc-11__ghost {
height: 42px;
padding: 0 16px;
border: 1px solid #d0d5dd;
border-radius: 10px;
cursor: pointer;
background: #fff;
color: #344054;
font-size: 13px;
font-weight: 600;
}
.cpc-11__ghost:hover {
border-color: var(--accent);
color: var(--accent);
}
.cpc-11__cta {
height: 42px;
padding: 0 18px;
border: none;
border-radius: 10px;
cursor: pointer;
background: var(--accent);
color: #fff;
font-size: 13px;
font-weight: 600;
}
.cpc-11__cta:hover {
background: color-mix(in oklch,var(--accent) 88%,#000);
}
.cpc-11__ghost:focus-visible,
.cpc-11__cta:focus-visible {
outline: 3px solid color-mix(in oklch,var(--accent) 45%,#fff);
outline-offset: 2px;
}
@container (max-width: 420px) {
.cpc-11__card {
flex-direction: column;
}
.cpc-11__img {
flex: none;
width: 100%;
aspect-ratio: 16/9;
}
}
@media (prefers-reduced-motion: reduce) {
}
```
## JavaScript
```js
/* No JavaScript — a @container query stacks the horizontal card when its wrapper narrows. */
```Here's a working CSS Product Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Horizontal Responsive Card
Source: https://codefronts.com/components/css-product-cards/horizontal-responsive-card/
A horizontal image-left / details-right card for cart pages, comparison rows and mobile search listings — that automatically stacks to vertical when its container gets narrow, using a container query rather than a viewport media query.
## HTML
```html
<div class="cpc-11">
<article class="cpc-11__wrap">
<div class="cpc-11__card">
<div class="cpc-11__img" role="img" aria-label="Product photo: Ridge insulated bottle"><span>product shot</span></div>
<div class="cpc-11__body">
<div><h3 class="cpc-11__name">Ridge Insulated Bottle · 750ml</h3><p class="cpc-11__meta">Slate · Keeps cold 24h</p></div>
<div class="cpc-11__foot">
<p class="cpc-11__price">$35</p>
<div class="cpc-11__actions">
<button type="button" class="cpc-11__ghost">Save</button>
<button type="button" class="cpc-11__cta">Add to Cart</button>
</div>
</div>
</div>
</div>
</article>
</div>
```
## CSS
```css
.cpc-11,
.cpc-11 *,
.cpc-11 *::before,
.cpc-11 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cpc-11 ::selection {
background: oklch(0.6 0.13 230);
color: #fff;
}
.cpc-11 {
--accent: oklch(0.52 0.14 235);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 20px;
background: #eef1f5;
}
.cpc-11__wrap {
container-type: inline-size;
width: min(520px,100%);
}
.cpc-11__card {
display: flex;
gap: 0;
background: #fff;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 14px 36px -20px rgba(16,24,40,.4);
}
.cpc-11__img {
flex: 0 0 40%;
aspect-ratio: 1/1;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg,#dbe3ee,#c9d5e6),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 0 12px,transparent 12px 24px);
}
.cpc-11__img {
background-image: url("https://loremflickr.com/600/600/waterbottle?lock=21");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.cpc-11__img span {
display: none;
}
.cpc-11__body {
flex: 1;
padding: 20px 22px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
}
.cpc-11__name {
font-size: 17px;
font-weight: 600;
color: #101828;
line-height: 1.35;
}
.cpc-11__meta {
margin-top: 4px;
font-size: 13px;
color: #667085;
}
.cpc-11__foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.cpc-11__price {
font-size: 20px;
font-weight: 800;
color: #101828;
}
.cpc-11__actions {
display: flex;
gap: 8px;
}
.cpc-11__ghost {
height: 42px;
padding: 0 16px;
border: 1px solid #d0d5dd;
border-radius: 10px;
cursor: pointer;
background: #fff;
color: #344054;
font-size: 13px;
font-weight: 600;
}
.cpc-11__ghost:hover {
border-color: var(--accent);
color: var(--accent);
}
.cpc-11__cta {
height: 42px;
padding: 0 18px;
border: none;
border-radius: 10px;
cursor: pointer;
background: var(--accent);
color: #fff;
font-size: 13px;
font-weight: 600;
}
.cpc-11__cta:hover {
background: color-mix(in oklch,var(--accent) 88%,#000);
}
.cpc-11__ghost:focus-visible,
.cpc-11__cta:focus-visible {
outline: 3px solid color-mix(in oklch,var(--accent) 45%,#fff);
outline-offset: 2px;
}
@container (max-width: 420px) {
.cpc-11__card {
flex-direction: column;
}
.cpc-11__img {
flex: none;
width: 100%;
aspect-ratio: 16/9;
}
}
@media (prefers-reduced-motion: reduce) {
}
```
## JavaScript
```js
/* No JavaScript — a @container query stacks the horizontal card when its wrapper narrows. */
```How this works
The card is a two-column flex row: a fixed-ratio image on the left, content on the right with a price and quantity/remove controls. The wrapper is a container, and a @container query flips the layout to a vertical stack once the card itself (not the whole viewport) drops below a threshold.
Container-based responsiveness means the same card works in a wide cart column and a narrow sidebar without knowing the page layout — exactly what a reusable component needs.
Make it yours
- Set the stack breakpoint by editing the
@containerwidth — tune it to where your image gets too small. - Swap the right-side controls (quantity stepper, remove, save-for-later) for your cart's actions.
- Change the image column ratio for a wider or thumbnail-sized media.
- Drop the container query and use a plain media query if you only ever place it full-width.
Gotchas — read before shipping
- Container queries need an ancestor with
container-type: inline-size— set it on the wrapper, not the card itself if the card is what you're querying. - Give the image a fixed aspect-ratio so rows stay aligned in a list.
- Keep the remove/quantity controls real buttons with labels — icon-only controls need
aria-label.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 113+ | 111+ |
Floor set by oklch(), color-mix(), @container as this demo is written. The core technique itself goes back further — Chrome 105+.
@container queries: Chrome 105+, Safari 16+, Firefox 110+. Falls back to the horizontal layout where unsupported.