A card is a bordered box that groups related content: a product, a blog post, a team member, a tour package. Bootstrap cards are one of the most used components because they are flexible. A card can hold an image, a title, text, links, a list or buttons, in almost any combination, and cards line up nicely in the grid.
The parts of a card
A card is built from a few nested classes. Only card is required; the rest are optional pieces you add as needed.
| Class | Purpose |
|---|---|
card | The outer box: border, rounded corners and a flex column layout |
card-body | The padded area for the main content |
card-title, card-subtitle | Headings with suitable spacing |
card-text | Paragraphs inside the body (removes the extra bottom margin on the last one) |
card-img-top, card-img-bottom | An image that fills the card width with matching rounded corners |
card-header, card-footer | Shaded strips above or below the body |
card-link | Links placed side by side at the bottom of the body |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A basic card</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container py-4">
<div class="card" style="max-width: 20rem;">
<svg class="card-img-top" width="100%" height="150" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Illustration of Marina Beach at sunrise" preserveAspectRatio="xMidYMid slice"><rect width="100%" height="100%" fill="#0d6efd"/><circle cx="80%" cy="35%" r="22" fill="#ffc107"/></svg>
<div class="card-body">
<h2 class="card-title h5">Marina Beach walk</h2>
<h3 class="card-subtitle h6 mb-2 text-body-secondary">Chennai · 2 hours</h3>
<p class="card-text">An early-morning walk along one of the longest urban beaches in India, ending with filter coffee.</p>
<a href="#" class="btn btn-primary">See details</a>
</div>
</div>
</div>
</body>
</html>Bootstrap cards have no fixed width. A card stretches to fill its parent, so you normally control the width with the grid or a utility rather than on the card itself. Here a small inline max-width keeps the single card narrow. The coloured image is a simple inline SVG so the example works offline; on a real site you would use <img src="…" class="card-img-top" alt="…"> with a meaningful alt text.
Headers, footers, lists and colours
A card-header works well for a category or a step label, and a card-footer for dates, prices or actions. You can also drop a list group straight into a card with list-group list-group-flush, which removes the outer borders so the list blends into the card. To colour a whole card, use text-bg-primary and friends on the card element, or just a coloured border such as border-success.
Card grids with equal heights
To show several Bootstrap cards, put them in the grid. The neatest way is row-cols-* on the row with a col around each card. Add h-100 to each card so all cards in a row have the same height, even when one has more text. Because a card is a flex column, a footer always sits at the bottom.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Equal-height card grid</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container py-4">
<h1 class="h3 mb-3">Weekend trips from Bengaluru</h1>
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card h-100">
<svg class="card-img-top" width="100%" height="150" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Green hills of Nandi" preserveAspectRatio="xMidYMid slice"><rect width="100%" height="100%" fill="#198754"/><circle cx="80%" cy="35%" r="22" fill="#d1e7dd"/></svg>
<div class="card-body">
<h2 class="card-title h5">Nandi Hills</h2>
<p class="card-text">Sunrise views above the clouds, about 60 km away.</p>
</div>
<div class="card-footer text-body-secondary">Day trip</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<svg class="card-img-top" width="100%" height="150" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Old stone ruins at Hampi" preserveAspectRatio="xMidYMid slice"><rect width="100%" height="100%" fill="#fd7e14"/><circle cx="80%" cy="35%" r="22" fill="#fff3cd"/></svg>
<div class="card-body">
<h2 class="card-title h5">Hampi</h2>
<p class="card-text">Boulder landscapes, the Vittala temple and coracle rides on the Tungabhadra. Plan at least two days to see the main sites without rushing.</p>
</div>
<div class="card-footer text-body-secondary">2–3 days</div>
</div>
</div>
<div class="col">
<div class="card h-100 border-primary">
<div class="card-header text-bg-primary">Popular</div>
<div class="card-body">
<h2 class="card-title h5">Mysuru</h2>
<p class="card-text">The palace, Chamundi Hill and silk shopping.</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">Mysore Palace</li>
<li class="list-group-item">Brindavan Gardens</li>
</ul>
<div class="card-footer text-body-secondary">Weekend</div>
</div>
</div>
</div>
</div>
</body>
</html>In the preview the three cards sit side by side and are all as tall as the tallest one. On a phone, row-cols-1 stacks them. Try deleting h-100 from one card to see the difference.
Tip: Bootstrap also has card-group, which joins cards edge to edge with no gaps, and the Masonry layout used by some sites needs an extra JavaScript library. For most designs, the grid with row-cols-* and g-* is the simplest and most flexible option. See Bootstrap Grid System for a refresher.
Horizontal cards and clickable cards
For a list of articles or search results, an image beside the text often reads better. Put a row g-0 inside the card, with the image in one column and the card-body in another. Use rounded-start on the image so only its left corners are rounded.
To make the whole card clickable, add stretched-link to the main link inside it. Bootstrap stretches an invisible layer from that link over its nearest positioned parent. The card is already position: relative, so the whole card becomes the click area while the link text remains the accessible name.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Horizontal, clickable card</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container py-4">
<div class="card mb-3" style="max-width: 560px;">
<div class="row g-0">
<div class="col-4">
<svg class="img-fluid rounded-start" width="100%" height="160" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Plate of Chettinad chicken" preserveAspectRatio="xMidYMid slice"><rect width="100%" height="100%" fill="#dc3545"/><circle cx="80%" cy="35%" r="22" fill="#f8d7da"/></svg>
</div>
<div class="col-8">
<div class="card-body">
<h2 class="card-title h5">A beginner's guide to Chettinad cooking</h2>
<p class="card-text">Kalpasi, marathi mokku and fresh pepper give Karaikudi dishes their deep flavour.</p>
<a href="#" class="stretched-link">Read the article</a>
<p class="card-text mt-2"><small class="text-body-secondary">8 min read</small></p>
</div>
</div>
</div>
</div>
<p id="msg" class="text-body-secondary">Click anywhere on the card.</p>
</div>
<script>
document.querySelector('.stretched-link').addEventListener('click', (event) => {
event.preventDefault();
document.getElementById('msg').textContent = 'The card link was clicked.';
});
</script>
</body>
</html>Watch out: Do not put other buttons or links inside a card that uses stretched-link. The stretched layer sits on top of them and swallows their clicks. If a card needs several actions, skip stretched-link and give each action its own clear button.
Design tips for Bootstrap cards
- Use a real heading element for the card title (
h2,h3…) so screen reader users can jump between cards. Useh5as a class to control the size. - Keep each card about one thing, with one main action.
- Give every image a meaningful
alttext, oralt=""if it is purely decorative. - Keep card text short. Cards are for scanning; the detail page is for reading.
