Building a Responsive Product Card
Assemble a polished, adaptive card from image, badge, content and actions.
The card is the workhorse of modern UI, and it is a perfect exercise in composition. Let us build one that looks intentional and adapts to its container.
The anatomy
- Media — a fixed
aspect-videobox withobject-coverso images never distort. - Badge — absolutely positioned over the media,
rounded-full. - Body — title, description with
line-clamp-2so long text never breaks the layout. - Footer — price and a call to action pushed apart with
justify-between.
The finishing touches that read as senior
A subtle border and a shadow, a hover that lifts (hover:-translate-y-1 hover:shadow-xl) with a transition, and consistent internal rhythm from a single spacing scale. Small moves, big polish.
<div class="rounded-2xl border border-slate-100 shadow
hover:-translate-y-1 hover:shadow-xl transition">
…
</div>Example
When to use it
- An e-commerce site displays product cards with image, badge, price, and an Add to Cart button that re-use the same Tailwind utility composition across hundreds of SKUs.
- A SaaS dashboard renders team-member cards with avatar, name, role badge, and action buttons — all built from aspect-ratio, object-cover, and flex utilities.
- A blog listing page shows article preview cards with a cover image, category tag, title, excerpt, and a Read More link, all responsive from a single class set.
More examples
Basic product card shell
Combines aspect-video + object-cover for a fixed-ratio image with overflow-hidden so it never bleeds outside the rounded card.
<div class="rounded-xl overflow-hidden shadow-md bg-white w-72">
<div class="aspect-video">
<img src="product.jpg" alt="Product" class="w-full h-full object-cover" />
</div>
<div class="p-4">
<span class="text-xs font-semibold uppercase tracking-wide text-cyan-600">New</span>
<h2 class="mt-1 text-lg font-bold text-gray-900">Wireless Headphones</h2>
<p class="mt-1 text-sm text-gray-500">Crystal-clear audio, 30 h battery.</p>
</div>
</div>Card with price and action row
Uses flex-col + flex-1 on the description so the price/action row always sits at the card bottom regardless of text length.
<div class="rounded-xl overflow-hidden shadow-md bg-white w-72 flex flex-col">
<div class="aspect-video">
<img src="product.jpg" alt="Product" class="w-full h-full object-cover" />
</div>
<div class="p-4 flex flex-col flex-1">
<h2 class="text-lg font-bold text-gray-900">Wireless Headphones</h2>
<p class="mt-1 text-sm text-gray-500 flex-1">Crystal-clear audio, 30 h battery.</p>
<div class="mt-4 flex items-center justify-between">
<span class="text-xl font-bold text-gray-900">$89</span>
<button class="px-4 py-2 rounded-lg bg-cyan-600 text-white text-sm font-semibold hover:bg-cyan-700">
Add to cart
</button>
</div>
</div>
</div>Responsive card grid with hover lift
Adds a group-hover image zoom and card lift effect with transition utilities, and wraps multiple cards in a responsive CSS Grid.
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
<div class="rounded-xl overflow-hidden shadow-md bg-white flex flex-col
transition-transform duration-200 hover:-translate-y-1 hover:shadow-xl
group">
<div class="aspect-video overflow-hidden">
<img src="product.jpg" alt="Product"
class="w-full h-full object-cover transition-transform duration-300
group-hover:scale-105" />
</div>
<div class="p-4 flex flex-col flex-1">
<span class="text-xs font-semibold uppercase tracking-wide text-cyan-600">Sale</span>
<h2 class="mt-1 text-lg font-bold text-gray-900">Wireless Headphones</h2>
<p class="mt-1 text-sm text-gray-500 flex-1">Crystal-clear audio, 30 h battery.</p>
<div class="mt-4 flex items-center justify-between">
<div>
<span class="text-xl font-bold text-gray-900">$89</span>
<span class="ml-2 text-sm line-through text-gray-400">$120</span>
</div>
<button class="px-4 py-2 rounded-lg bg-cyan-600 text-white text-sm font-semibold
hover:bg-cyan-700 focus:outline-none focus:ring-2 focus:ring-cyan-400">
Add to cart
</button>
</div>
</div>
</div>
</div>
Discussion