How to Create a Card in CSS
Build a reusable card component that groups an image, heading, description, and action into one visually distinct block.
What makes a card a card
A card is a self-contained block of related content - typically an image, a title, some supporting text, and an optional action - set apart from the rest of the page with a border, shadow, or background color. Cards are the standard way to present a list of similar things (products, articles, team members) as a scannable grid.
Structurally, a card is just a container element with a few semantic children. The visual identity comes entirely from CSS: padding for breathing room, a border-radius for softened corners, and a box-shadow to lift it off the background.
Example: a single card
<!DOCTYPE html>
<html>
<head>
<style>
.card {
max-width: 320px;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
overflow: hidden; /* clips the image to the rounded corners */
font-family: system-ui, sans-serif;
}
.card img {
width: 100%;
height: 160px;
object-fit: cover; /* fills the box without distorting the image */
display: block;
}
.card-body {
padding: 16px 20px 20px;
}
.card-title {
margin: 0 0 8px;
font-size: 1.1rem;
}
.card-text {
margin: 0 0 16px;
color: #5b6472;
font-size: 0.9rem;
line-height: 1.5;
}
.card-action {
display: inline-block;
background: #2563eb;
color: #fff;
text-decoration: none;
padding: 8px 16px;
border-radius: 6px;
font-size: 0.9rem;
}
.card-action:hover {
background: #1d4ed8;
}
</style>
</head>
<body>
<div class="card">
<img src="https://picsum.photos/id/1025/320/160" alt="A dog sitting in snow">
<div class="card-body">
<h3 class="card-title">Winter Hikes</h3>
<p class="card-text">A short guide to keeping your dog warm and safe on cold-weather trails.</p>
<a class="card-action" href="#">Read more</a>
</div>
</div>
</body>
</html>Laying out a grid of cards
Cards are almost always shown in groups. `display: grid` with `grid-template-columns: repeat(auto-fit, minmax(240px, 1fr))` produces a responsive grid that fits as many cards per row as will comfortably fit, and reflows to fewer columns automatically as the viewport shrinks - no media queries required.
Example: responsive card grid
<!DOCTYPE html>
<html>
<head>
<style>
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 20px;
}
</style>
</head>
<body>
<div class="card-grid">
<div class="card"><!-- card 1 content --></div>
<div class="card"><!-- card 2 content --></div>
<div class="card"><!-- card 3 content --></div>
</div>
</body>
</html>`auto-fit` tells the grid to collapse empty tracks, so a row with only two cards stretches them to fill the space rather than leaving a gap; `minmax(240px, 1fr)` sets a floor of 240px per card while letting them grow evenly to fill any extra width.
- Use semantic tags inside the card (h3 for the title, p for the description, a for the action) so the content makes sense even without the CSS.
- Keep the whole card clickable by wrapping it in an <a> tag when the card links to one destination, rather than only making a small 'Read more' link clickable.
- Cap image height with a fixed value plus object-fit: cover so mismatched image sizes don't break the grid's alignment.
Frequently Asked Questions
- How do I create a card component in CSS?
- Use a container with padding, a border or subtle shadow, and
border-radius. Put the image first withwidth: 100%, then the text content. Flex column layout keeps the spacing even as content length varies. - How do I make cards the same height in a row?
- Put them in a flex or grid container. Both stretch children to match the tallest by default. Inside each card, use
margin-top: autoon the footer so buttons align across cards even when the text above differs in length.