Product card with CSS

This tutorial shows how to create a simple product card with CSS.

FrontendCSSUI designTutorial

Posted on: 11/20/2022

By: Mirado Andria

If you create an e-commerce website, or a website for a company, there is a good chance that you will present the list of products or services offered.

In this mini-tutorial, I will show you how to make a product card with CSS. The result will be as follows:

Result card

HTML Structure

Here is the basic structure in HTML:

<div class="card-product"> <img class="card-img" src="leaves.jpg" alt="Card image ..." /> <div class="card-top"> <p class="price">$199</p> </div> <div class="card-bottom"> <h4 class="category">Decoration</h4> <h3 class="title">Plante verte</h3> </div> </div>
  • card-product is the main card wrapper.
  • card-img represents the product image.
  • card-top represents what will be displayed at the top of the card (Product price).
  • And card-footer represents the elements at the bottom (Product name, category).


Here is the equivalent in React (TypeScript):

export default function ProductCard({ name, price, category, imageUrl, }: { name: string, price: number, category: string, imageUrl: string, }) { return ( <div className="card-product"> <img className="card-img" src={imageUrl} alt="Card image ..." /> <div className="card-top"> <p className="price">${price}</p> </div> <div className="card-bottom"> <h4 className="category">{category}</h4> <h3 className="title">{name}</h3> </div> </div> ); }


Here are the CSS rules we apply to these elements:

.card-product { display: block; border-radius: 1rem; overflow: hidden; color: #41425b; box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.16); position: relative; aspect-ratio: 4/3; width: 22.5rem; background-color: #e1e1e1; } .card-product .card-img { position: relative; z-index: 0; width: 100%; height: 100%; object-fit: cover; display: block; } .card-product .card-top { position: absolute; z-index: 1; left: 1.5rem; top: 1.5rem; } .card-product .card-bottom { position: absolute; z-index: 1; left: 1.5rem; bottom: 1.5rem; } .card-product .price { margin: 0; font-size: 1.5rem; } .card-product .title { margin: 0.5rem 0 0 0; font-size: 2rem; font-weight: bold; } .card-product .category { margin: 0; font-size: 1.25rem; font-weight: normal; }

About the main wrapper card-product, here we use the aspect-ratio CSS property so that the cards have the same proportion. Here, we set its value to 4/3 but you can change it (eg 1/1 for a square card).

We use the relative value for the position property, so that child elements with absolute position, position themselves relative to this element.

We added a box-shadow so that the card has an elevated appearance.

For the product image card-img, we use the object-fit: cover declaration so that the image is not distorted. It is recommended to use an image with the same proportion as the aspect-ratio of the card-product wrapper.

card-top and card-bottom are placed in absolute position, one at the top (top: 1.5rem) and the other at the bottom (bottom: 1.5rem). We added a z-index to place them above other elements (such as the image).


As an extension or improvement of the project, you can try to use flexbox to distribute the layout of the card (card-top and card-bottom). You can also add animations (zoom of the image on hover for example).

I hope you liked this mini-tutorial.


You can find the source code here.

JavaScript Parallel async

JavaScript Parallel async


Run several async tasks in parallel with JavaScript.

CSS Gradient text

CSS Gradient text


Use gradient color as text color and add color animation.