Bootstrap 5 Comparison Table
A comparison table is a structured UI pattern that places two or more options side by side in a tabular layout so users can evaluate features at a glance. It is composed from Bootstrap 5's table utilities (.table, .table-bordered, .table-striped), sticky positioning, badge components, and flex utilities — Bootstrap ships none of this as a named component. Use it whenever a product, pricing, or feature decision benefits from a direct column-by-column contrast.
Primary Class
.table .table-borderedCommon Use Cases
- →A SaaS product page comparing Free, Pro, and Enterprise subscription tiers across a list of feature limits and support levels.
- →A hosting provider's documentation page contrasting shared, VPS, and dedicated server specifications such as CPU, RAM, and bandwidth.
- →An e-commerce site's buying guide placing three camera models side by side with sensor size, weight, and battery life values.
- →A government procurement portal displaying tender responses from multiple suppliers against a fixed set of evaluation criteria.
Variants & Classes
| Variant | Description |
|---|---|
| Basic Feature Comparison | A plain bordered table with a sticky first column and tick/cross icons to indicate feature availability per plan. |
| Highlighted Column | One column is visually promoted with a background colour and a 'Most Popular' badge pinned to its header to draw attention. |
| Striped Responsive Wrapper | Wrapped in a div with overflow-x-auto and table-striped so the table scrolls horizontally on small screens without breaking the layout. |
| Card-based Column Layout | Instead of a traditional table element, Bootstrap card and grid columns simulate a comparison layout for fully custom styling per plan. |
Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pricing Comparison Table</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<style>
.comparison-table th:first-child,
.comparison-table td:first-child {
position: sticky;
left: 0;
background-color: var(--bs-body-bg);
z-index: 1;
border-right: 2px solid var(--bs-border-color);
font-weight: 600;
}
.comparison-table thead th.col-highlight {
background-color: var(--bs-primary);
color: #fff;
}
.comparison-table tbody td.col-highlight {
background-color: var(--bs-primary-bg-subtle);
}
.tick { color: #198754; font-size: 1.15rem; }
.cross { color: #dc3545; font-size: 1.15rem; }
</style>
</head>
<body class="py-5">
<div class="container">
<h2 class="mb-1 fw-bold text-center">Choose Your Plan</h2>
<p class="text-center text-muted mb-4">All plans include a 14-day free trial. No credit card required.</p>
<div class="table-responsive">
<table class="table table-bordered table-hover align-middle comparison-table">
<thead class="table-dark">
<tr>
<th scope="col" style="min-width:200px">Feature</th>
<th scope="col" class="text-center" style="min-width:140px">Free</th>
<th scope="col" class="text-center col-highlight" style="min-width:140px">
Pro
<span class="badge bg-warning text-dark ms-1">Popular</span>
</th>
<th scope="col" class="text-center" style="min-width:140px">Enterprise</th>
</tr>
</thead>
<tbody>
<tr>
<td>Monthly price</td>
<td class="text-center">£0</td>
<td class="text-center col-highlight fw-semibold">£19</td>
<td class="text-center">£79</td>
</tr>
<tr>
<td>Team members</td>
<td class="text-center">1</td>
<td class="text-center col-highlight">Up to 10</td>
<td class="text-center">Unlimited</td>
</tr>
<tr>
<td>Storage</td>
<td class="text-center">5 GB</td>
<td class="text-center col-highlight">50 GB</td>
<td class="text-center">1 TB</td>
</tr>
<tr>
<td>Custom domain</td>
<td class="text-center"><span class="cross" aria-label="Not included">✗</span></td>
<td class="text-center col-highlight"><span class="tick" aria-label="Included">✓</span></td>
<td class="text-center"><span class="tick" aria-label="Included">✓</span></td>
</tr>
<tr>
<td>Priority support</td>
<td class="text-center"><span class="cross" aria-label="Not included">✗</span></td>
<td class="text-center col-highlight"><span class="tick" aria-label="Included">✓</span></td>
<td class="text-center"><span class="tick" aria-label="Included">✓</span></td>
</tr>
<tr>
<td>SSO & SAML</td>
<td class="text-center"><span class="cross" aria-label="Not included">✗</span></td>
<td class="text-center col-highlight"><span class="cross" aria-label="Not included">✗</span></td>
<td class="text-center"><span class="tick" aria-label="Included">✓</span></td>
</tr>
<tr>
<td>SLA uptime guarantee</td>
<td class="text-center">99.5%</td>
<td class="text-center col-highlight">99.9%</td>
<td class="text-center">99.99%</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td class="text-center"><a href="#" class="btn btn-outline-secondary btn-sm">Get started</a></td>
<td class="text-center col-highlight"><a href="#" class="btn btn-primary btn-sm">Start free trial</a></td>
<td class="text-center"><a href="#" class="btn btn-outline-dark btn-sm">Contact sales</a></td>
</tr>
</tfoot>
</table>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>Live Examples
Simple Two-Column Feature List
A minimal table comparing two product editions with text values. No sticky column required because there are few columns and the table fits on most screens.
Card-based Plan Comparison
Uses Bootstrap grid and card components instead of a table element, giving full control over per-column styling and making each plan a distinct card on desktop.
Striped Scrollable Specification Table
A horizontally scrollable, striped table suited to comparing technical specifications such as hardware components where many narrow columns are needed.
Canvas Framework Variants
The Canvas template extends Bootstrap 5 with 1,658+ component variants. Generate any of these using Canvas Builder:
- ✓Pricing comparison table with highlighted 'Most Popular' column — generated automatically by Canvas Builder from a pricing prompt
- ✓Three-tier SaaS feature matrix with tick and cross icons
- ✓Card-based plan comparison with per-column CTA buttons
- ✓Scrollable hardware specification table with sticky feature column
- ✓Dark-header comparison table with badge labels on premium tiers
Best Practices
Sticky first column on wide tables
Apply position: sticky; left: 0 to the first th and td in each row using a shared class, and set a solid background colour matching the page so cells do not bleed through when the table scrolls horizontally. Always add z-index: 1 to prevent the sticky cell from rendering beneath other cells.
Accessibility for tick and cross icons
Avoid relying solely on colour or decorative characters to convey availability. Add aria-label="Included" or aria-label="Not included" to each icon element so screen readers can interpret the value correctly. Consider supplementing icons with visually hidden text via Bootstrap's .visually-hidden class for maximum compatibility.
Highlighting a recommended column
Use Bootstrap's contextual colour utilities such as bg-primary-subtle on tbody cells and bg-primary on the thead cell to highlight a recommended plan. Pair this with a .badge inside the header cell to reinforce the recommendation visually without altering the table's semantic structure.
Responsive behaviour at small breakpoints
Wrap the table in a div with the .table-responsive class to enable horizontal scrolling on viewports narrower than the table's natural width. For card-based layouts, switch to Bootstrap's grid (col-12 col-md-4) so each plan stacks vertically on mobile and expands to side-by-side columns on medium and larger screens.