12 / 18
All 18 in 18 Tailwind CSS Product Cards
- 01Tailwind Product Card with Hover-Reveal Add to Cart
- 02Pure-Tailwind 3D Flip Product Card with Spec Back
- 03Tailwind Contained Image Zoom Product Card
- 04Tailwind Mouse-Tracking 3D Tilt Product Card
- 05Tailwind Slide-Up Details Panel Product Card
- 06Tailwind Minimalist eCommerce Product Card
- 07Tailwind Glassmorphism Product Card
- 08Tailwind Dark-Mode Gadget Product Card with Accent Glow
- 09Tailwind Neon Glowing Conic-Border Product Card
- 10Tailwind Material-Design Elevation Product Card
- 11Tailwind Horizontal Product Card with Container Queries
- 12Tailwind Auto-Fit Product Catalog Grid
- 13Tailwind Sale Ribbon & Coupon Badge Product Card
- 14Tailwind Sneaker Card with Colourway & Size Picker
- 15Tailwind Digital Download Product Card
- 16Tailwind Food Delivery Card with Quantity Stepper
- 17Tailwind Real Estate Listing Card with Favourite Toggle
- 18Tailwind Subscription Pricing Card with Billing Switch
Tailwind Auto-Fit Product Catalog Grid
Not one card but the container: a catalog that fits as many ≥200px columns as the space allows, with zero breakpoints. Tailwind's grid-cols-* scale is integers, so the whole pattern is one honest arbitrary value — grid-cols-[repeat(auto-fit,minmax(200px,1fr))] — and the six cells are a tiny compact card repeated.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tpc-12 w-full min-h-svh grid place-items-center bg-tpc12-bg font-tpc12-sans px-5 py-12" aria-label="Auto-fit product catalog grid demo">
<div class="w-[min(920px,100%)] grid gap-5 content-start grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: canvas sneaker" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Canvas Sneaker</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$68</span>
<button type="button" aria-label="Add Canvas Sneaker to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: merino crew sweatshirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1620799140408-edc6dcb6d633?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Merino Crew</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$24</span>
<button type="button" aria-label="Add Wool Beanie to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: denim jacket" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1543076447-215ad9ba6923?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Denim Jacket</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$96</span>
<button type="button" aria-label="Add Denim Jacket to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: linen shirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1596755094514-f87e34085b2c?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Linen Shirt</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$54</span>
<button type="button" aria-label="Add Linen Shirt to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: trail cap" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Trail Cap</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$29</span>
<button type="button" aria-label="Add Trail Cap to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: suede loafer" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1533867617858-e7b97e060509?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Suede Loafer</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$120</span>
<button type="button" aria-label="Add Suede Loafer to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
</div>
</section><section class="tpc-12 w-full min-h-svh grid place-items-center bg-tpc12-bg font-tpc12-sans px-5 py-12" aria-label="Auto-fit product catalog grid demo">
<div class="w-[min(920px,100%)] grid gap-5 content-start grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: canvas sneaker" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Canvas Sneaker</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$68</span>
<button type="button" aria-label="Add Canvas Sneaker to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: merino crew sweatshirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1620799140408-edc6dcb6d633?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Merino Crew</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$24</span>
<button type="button" aria-label="Add Wool Beanie to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: denim jacket" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1543076447-215ad9ba6923?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Denim Jacket</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$96</span>
<button type="button" aria-label="Add Denim Jacket to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: linen shirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1596755094514-f87e34085b2c?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Linen Shirt</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$54</span>
<button type="button" aria-label="Add Linen Shirt to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: trail cap" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Trail Cap</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$29</span>
<button type="button" aria-label="Add Trail Cap to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: suede loafer" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1533867617858-e7b97e060509?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Suede Loafer</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$120</span>
<button type="button" aria-label="Add Suede Loafer to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
</div>
</section>@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The grid template is the collection's clearest example of a correct arbitrary value:
grid-cols-*is an integer scale by design, andrepeat(auto-fit,minmax(200px,1fr))is asking the browser to compute the count instead. - Six
:nth-childbackground-image rules in the CSS version become sixbg-[url(…)]utilities on the elements that show them. Adding a seventh product no longer means editing the stylesheet. - Each card carries its own
group. A single group on the grid — the tempting shorter version — would lift every card on any hover. content-startreplaces the original's flex centring, so a partial last row keeps its cards at natural height.- Enhancement over the CSS original: the add-buttons grew from 40px to 44px, gained
focus-within:lift parity, and every thumbnail kept a gradient under its URL so a failed request still reads as a product.
Here's a working CSS demo 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: Tailwind Auto-Fit Product Catalog Grid
Source: https://codefronts.com/components/tailwind-css-product-cards/tailwind-auto-fit-product-catalog-grid/
Not one card but the container: a catalog that fits as many ≥200px columns as the space allows, with zero breakpoints. Tailwind's grid-cols-* scale is integers, so the whole pattern is one honest arbitrary value — grid-cols-[repeat(auto-fit,minmax(200px,1fr))] — and the six cells are a tiny compact card repeated.
## HTML
```html
<section class="tpc-12 w-full min-h-svh grid place-items-center bg-tpc12-bg font-tpc12-sans px-5 py-12" aria-label="Auto-fit product catalog grid demo">
<div class="w-[min(920px,100%)] grid gap-5 content-start grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: canvas sneaker" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Canvas Sneaker</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$68</span>
<button type="button" aria-label="Add Canvas Sneaker to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: merino crew sweatshirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1620799140408-edc6dcb6d633?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Merino Crew</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$24</span>
<button type="button" aria-label="Add Wool Beanie to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: denim jacket" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1543076447-215ad9ba6923?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Denim Jacket</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$96</span>
<button type="button" aria-label="Add Denim Jacket to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: linen shirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1596755094514-f87e34085b2c?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Linen Shirt</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$54</span>
<button type="button" aria-label="Add Linen Shirt to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: trail cap" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Trail Cap</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$29</span>
<button type="button" aria-label="Add Trail Cap to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: suede loafer" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1533867617858-e7b97e060509?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Suede Loafer</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$120</span>
<button type="button" aria-label="Add Suede Loafer to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}
```Here's a working CSS demo 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: Tailwind Auto-Fit Product Catalog Grid
Source: https://codefronts.com/components/tailwind-css-product-cards/tailwind-auto-fit-product-catalog-grid/
Not one card but the container: a catalog that fits as many ≥200px columns as the space allows, with zero breakpoints. Tailwind's grid-cols-* scale is integers, so the whole pattern is one honest arbitrary value — grid-cols-[repeat(auto-fit,minmax(200px,1fr))] — and the six cells are a tiny compact card repeated.
## HTML
```html
<section class="tpc-12 w-full min-h-svh grid place-items-center bg-tpc12-bg font-tpc12-sans px-5 py-12" aria-label="Auto-fit product catalog grid demo">
<div class="w-[min(920px,100%)] grid gap-5 content-start grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: canvas sneaker" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Canvas Sneaker</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$68</span>
<button type="button" aria-label="Add Canvas Sneaker to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: merino crew sweatshirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1620799140408-edc6dcb6d633?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Merino Crew</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$24</span>
<button type="button" aria-label="Add Wool Beanie to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: denim jacket" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1543076447-215ad9ba6923?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Denim Jacket</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$96</span>
<button type="button" aria-label="Add Denim Jacket to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: linen shirt" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1596755094514-f87e34085b2c?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Linen Shirt</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$54</span>
<button type="button" aria-label="Add Linen Shirt to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: trail cap" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1588850561407-ed78c282e89b?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Trail Cap</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$29</span>
<button type="button" aria-label="Add Trail Cap to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
<article class="group rounded-[14px] overflow-hidden pb-3.5 bg-tpc12-card shadow-[0_10px_26px_-18px_oklch(0.25_0.03_50/0.4)] transition-[translate,box-shadow] duration-250 hover:-translate-y-1 hover:shadow-[0_20px_40px_-20px_oklch(0.25_0.03_50/0.45)] focus-within:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div role="img" aria-label="Product photo: suede loafer" class="aspect-square bg-linear-[135deg,var(--color-tpc12-ph),var(--color-tpc12-ph2)] bg-[url('https://images.unsplash.com/photo-1533867617858-e7b97e060509?w=500&h=500&fit=crop&q=70')] bg-cover bg-center"></div>
<h3 class="px-3.5 pt-3.5 text-[15px] font-semibold text-tpc12-ink">Suede Loafer</h3>
<div class="flex items-center justify-between gap-2 px-3.5 pt-2">
<span class="text-base font-extrabold text-tpc12-acc tabular-nums">$120</span>
<button type="button" aria-label="Add Suede Loafer to cart" class="grid place-items-center min-w-11 min-h-11 rounded-[10px] border-0 bg-tpc12-acc text-tpc12-onacc text-[22px] leading-none font-semibold cursor-pointer transition-colors duration-150 hover:bg-tpc12-acc2 focus-visible:outline-3 focus-visible:outline-tpc12-ring focus-visible:outline-offset-2 motion-reduce:transition-none">+</button>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tpc12-bg: #f5f4f2;
--color-tpc12-bg: oklch(0.96 0.004 70);
--color-tpc12-card: #ffffff;
--color-tpc12-card: oklch(1 0 0);
--color-tpc12-ink: #2a2118;
--color-tpc12-ink: oklch(0.27 0.02 60);
--color-tpc12-ph: #ece7e2;
--color-tpc12-ph: oklch(0.93 0.01 60);
--color-tpc12-ph2: #ddd4cb;
--color-tpc12-ph2: oklch(0.87 0.018 60);
--color-tpc12-acc: #b23a26;
--color-tpc12-acc: oklch(0.52 0.16 30);
--color-tpc12-acc2: #94301f;
--color-tpc12-acc2: oklch(0.45 0.15 30);
--color-tpc12-onacc: #ffffff;
--color-tpc12-onacc: oklch(1 0 0);
--color-tpc12-ring: #e8a898;
--color-tpc12-ring: oklch(0.78 0.09 30);
--font-tpc12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tpc-12 {
width: 100%;
min-height: 100svh;
}
.tpc-12 ::selection {
background: var(--color-tpc12-acc);
color: #fff;
}
```How this works
The arbitrary value is the correct answer here.
<div class="grid gap-5 grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">Tailwind's grid-cols-1…12 are fixed track counts — useful, and the opposite of what this layout does. auto-fit + minmax asks the browser to decide the count from available width, so it reflows 4-up → 3-up → 2-up → 1-up with no breakpoint anywhere. Reaching for sm:grid-cols-2 lg:grid-cols-4 instead is the classic mistake: it hard-codes viewport assumptions into a component that did not need them.
auto-fit versus auto-fill. auto-fit collapses empty tracks and lets the remaining cards stretch; auto-fill keeps the empty tracks so a two-card last row stays card-width. Catalogs almost always want auto-fit; a fixed-size poster grid wants auto-fill.
Each cell is its own group. Six group classes, six independent hovers. One group on the grid would lift all six cards whenever the cursor touched any of them.
Make it yours
- Column density: the
200pxminimum. 160px for accessories, 280px for furniture. auto-fillinstead ofauto-fitif trailing empty tracks should be preserved.- Gap:
gap-5→gap-3for a dense grid,gap-8for an airy one. - Equal-height rows: add
auto-rows-frso uneven cards in a row share a height. - Cap the catalog width with the wrapper's
max-w-[920px], or remove it to fill any container.
Gotchas — read before shipping
- Don't replace the arbitrary value with breakpoint variants.
sm:grid-cols-2 lg:grid-cols-4responds to the viewport; this responds to the container, which is what a reusable catalog needs. - A very small
minmaxminimum produces absurdly narrow cards on wide screens — clamp it to something you would actually ship. - Images need a fixed
aspect-*or the grid jogs as they load. - Icon-only add-buttons must name their product in
aria-label; six identical '+' buttons are meaningless to a screen reader. auto-fitstretches cards to fill the row, so a catalog of three items in a 1200px container gives you three very wide cards. That is usually right; if it is not, you wantauto-fill.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
CSS Grid with auto-fit and minmax() has been supported since 2017; the floor quoted is Tailwind v4's own generated sheet.