Responsive Product Card Html Css Codepen

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);