Imagine a craftsman named Elias who spent months building the perfect leather bag. He takes a beautiful photo and puts it on his website. He writes the price, a lovely description, and waits for sales.
But nobody buys it.
Why? Because on a mobile phone, the photo was tiny, the "Buy" button was hidden off-screen, and the text was cramped. On a desktop monitor, the image was stretched and pixelated. Elias had a great product, but his "digital shop window" was broken.
This is the story of how we fix Elias's problem using Responsive Web Design. We are going to build a product card that adapts to its environment—tall and narrow on phones, wide and elegant on desktops.
Now for the magic. We need to style the card to handle different screen sizes.
You might notice that our CSS was written "Mobile First." We set width: 90% on the card initially, which is perfect for mobile devices.
However, if you are displaying a grid of cards (like a shop page), you will need media queries.
If you are using this card inside a grid (like an online store), you would structure your media query like this:
/* Example Grid Container */
.shop-container
display: grid;
grid-template-columns: 1fr; /* 1 column on mobile */
gap: 20px;
padding: 20px;
/* Tablet View */
@media (min-width: 600px)
.shop-container
grid-template-columns: repeat(2, 1fr); /* 2 columns */
/* Desktop View */
@media (min-width: 1000px)
.shop-container
grid-template-columns: repeat(4, 1fr); /* 4 columns */
We use CSS Grid and Flexbox. Notice how we switch layouts using a media query without writing duplicate code.
/* --- Global Reset & Setup --- */ * box-sizing: border-box; margin: 0; padding: 0;body font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f0f2f5; display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 20px;
/* --- The Container (Just for demo centering) --- / .product-container width: 100%; max-width: 800px; / Limits width on huge screens */ responsive product card html css codepen
/* --- The Card Logic --- / .product-card background: white; border-radius: 12px; overflow: hidden; / Keeps image inside the rounded corners */ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
/* MOBILE DEFAULT: Column Layout */ display: flex; flex-direction: column;
/* Smooth transition for hover effects */ transition: transform 0.3s ease, box-shadow 0.3s ease;
/* Hover Interaction for Desktop */ .product-card:hover transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0,0,0,0.15);
/* --- Image Section --- / .product-image position: relative; flex-shrink: 0; height: 250px; / Fixed height for mobile */ overflow: hidden;
.product-image img width: 100%; height: 100%; object-fit: cover; /* Prevents image distortion */ transition: transform 0.5s ease;
.product-card:hover .product-image img transform: scale(1.05); /* Subtle zoom on hover */
.product-badge position: absolute; top: 15px; left: 15px; background: #e74c3c; color: white; padding: 5px 12px; border-radius: 20px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
/* --- Details Section --- / .product-details padding: 25px; display: flex; flex-direction: column; gap: 15px; flex-grow: 1; / Ensures content fills available space */
.product-title font-size: 1.5rem; color: #2c3e50; font-weight: 700; Imagine a craftsman named Elias who spent months
.product-subtitle color: #7f8c8d; font-size: 0.9rem; margin-top: -10px;
.product-description color: #555; line-height: 1.6; font-size: 0.95rem;
/* --- Footer & Price --- / .product-footer margin-top: auto; / Pushes footer to the bottom */ display: flex; justify-content: space-between; align-items: center; border-top: 1px solid #eee; padding-top: 20px;
.price-current font-size: 1.25rem; font-weight: 700; color: #27ae60;
.price-original font-size: 0.9rem; color: #95a5a6; text-decoration: line-through; margin-left: 10px;
.add-to-cart background-color: #2c3e50; color: white; border: none; padding: 10px 20px; border-radius: 6px; font-weight: 600; cursor: pointer; transition: background-color 0.2s;
.add-to-cart:hover background-color: #34495e;
/* --- RESPONSIVE BREAKPOINT (Tablet/Desktop) --- / @media (min-width: 600px) .product-card / Switch to side-by-side layout / flex-direction: row; max-width: 700px; / Prevent card from getting too wide */
.product-image /* Image takes up 45% of the width / width: 45%; height: auto; / Height is now determined by content side */
.product-details /* Content takes remaining space */ width: 55%; padding: 30px;We use CSS Grid and Flexbox
Here we add the typography and the button styling.
.product-info
padding: 20px;
.product-category
font-size: 0.8rem;
text-transform: uppercase;
color: #888;
letter-spacing: 1px;
.product-title
margin: 10px 0;
font-size: 1.4rem;
color: #333;
.product-description
font-size: 0.9rem;
color: #666;
line-height: 1.5;
margin-bottom: 15px;
.product-price
margin-bottom: 15px;
.current-price
font-size: 1.3rem;
font-weight: bold;
color: #e63946;
.original-price
font-size: 1rem;
text-decoration: line-through;
color: #999;
margin-left: 10px;
.add-to-cart
width: 100%;
padding: 12px 0;
background-color: #333;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
font-weight: 600;
transition: background-color 0.3s ease;
.add-to-cart:hover
background-color: #e63946;
.products-grid display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; padding: 20px;.product-card flex: 1 1 250px; /* Grow, Shrink, Basis */ max-width: 300px; background: white; border-radius: 12px; padding: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); transition: transform 0.2s; text-align: center;
.product-card:hover transform: translateY(-5px);
img width: 100%; height: auto; border-radius: 8px;
@media (max-width: 768px) .product-card flex: 1 1 100%; /* Takes full width on mobile */
Why this works: The flex: 1 1 250px tells each card to try to be 250px wide, but if the container shrinks, they shrink proportionally. The media query forces full width below 768px.
For a responsive card, the image is usually the tricky part. We want to ensure it doesn't distort.
.product-image
position: relative;
height: 250px;
overflow: hidden;
.product-image img
width: 100%;
height: 100%;
object-fit: cover; /* Crops image nicely to fill the container */
transition: transform 0.5s ease;
/* Zoom effect on hover */
.product-card:hover .product-image img
transform: scale(1.05);