Bootstrap 5 cheat sheet
A scannable Bootstrap 5 reference: 15 short snippets across 9 topics, each linking back to the lesson it came from.
At a glance
| Topic | What it covers | |
|---|---|---|
| The grid system | Containers, rows and columns, the six breakpoints, gutter classes, and the layout recipes that cover most pages | lesson |
| Utilities and Sass customisation | Setting data-bs-theme on any element switches that subtree. Components are built from CSS custom properties such as | lesson |
| Layout beyond the grid: positioning and spacing recipes | The grid handles content columns, but the outer frame of a page — a header, a sidebar, a scrolling main area — is a | lesson |
| Typography, tables, images and content components | Bootstrap does not restyle your h1 to a smaller size in nested contexts the way Bootstrap 4 did. Instead you detach the | lesson |
| Forms in depth | Bootstrap's validation classes are presentation only: nothing is checked for you. The two legitimate triggers are the | lesson |
| Overlays: tooltips, popovers and toasts | Tooltips and popovers are opt-in: nothing is initialised from data attributes alone. They also do not appear on touch | lesson |
| Accessibility with Bootstrap | What the framework handles for free, what you still owe, and how to test the result with a keyboard before shipping | lesson |
| Theming with CSS variables, RTL and colour modes | Every Bootstrap 5 component reads its colours and geometry from local custom properties, so a theme can be applied with | lesson |
| Migrating from Bootstrap 4 and knowing the limits | The honest summary: the framework saves the most time on the parts nobody enjoys writing — modals, dropdown focus | lesson |
Quick snippets
The grid system
Containers, rows and columns
npm install bootstrap
# the compiled files you link to
# node_modules/bootstrap/dist/css/bootstrap.min.css
# node_modules/bootstrap/dist/js/bootstrap.bundle.min.js (Popper included)
Containers, rows and columns
<div class="container">
<div class="row">
<div class="col">first</div>
<div class="col">second</div>
<div class="col">third</div>
</div>
</div>
Breakpoints and column classes
<div class="col-12 col-sm-6 col-lg-4 col-xxl-3">card</div>
<div class="d-sm-none">phones only</div>
<div class="d-none d-md-block">hidden below 768px</div>
<div class="col-md-6 offset-md-3">centred column on medium and up</div>Full lesson: The grid system →
Utilities and Sass customisation
Utilities and helper classes
<div class="d-flex align-items-center gap-3 p-3 mb-4 rounded-3 border bg-body-tertiary shadow-sm">
<span class="text-truncate flex-fill fs-5 fw-semibold">A long title that truncates</span>
<button class="btn btn-sm btn-outline-secondary" aria-label="Close">×</button>
</div>
<p class="text-body-secondary small mb-0">Fine print</p>
<span class="visually-hidden">Screen-reader label</span>
Colour modes
<html lang="en" data-bs-theme="dark">
Colour modes
const root = document.documentElement;
// follow the operating system on first visit
const prefersDark = matchMedia('(prefers-color-scheme: dark)').matches;
root.setAttribute('data-bs-theme', localStorage.getItem('theme') || (prefersDark ? 'dark' : 'light'));
toggle.addEventListener('click', () => {
const next = root.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark';
root.setAttribute('data-bs-theme', next);
localStorage.setItem('theme', next);
});Full lesson: Utilities and Sass customisation →
Layout beyond the grid: positioning and spacing recipes
Sticky versus fixed
<!-- sticky sub-nav inside a scrolling page -->
<div class="position-sticky top-0 bg-body py-2 border-bottom" style="z-index: 1020;">
<span class="text-body-secondary small">Section navigation</span>
</div>
<!-- sticky table header inside a scroll container -->
<div class="table-responsive" style="max-height: 380px; overflow-y: auto;">
<table class="table table-sm mb-0">
<thead class="position-sticky top-0 bg-body"><tr><th scope="col">Order</th><th scope="col">Total</th></tr></thead>
<tbody><tr><td>#1041</td><td>82.00</td></tr></tbody>
</table>
</div>
Sticky versus fixed
<div class="position-relative">
<button type="button" class="btn btn-primary">Inbox</button>
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger">
9<span class="visually-hidden">unread messages</span>
</span>
</div>
Viewport units, spacing and overflow
/* Bootstrap gives you the building blocks; a page-specific rule is still the
right tool when you need a literal value. */
.hero {
min-height: 60vh; /* NOT min-vh-60: Bootstrap has no such class */
margin-top: calc(-1 * var(--bs-navbar-height, 3.5rem));
}
.kanban {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1rem;
}Full lesson: Layout beyond the grid: positioning and spacing recipes →
Typography, tables, images and content components
Tables that survive real data
<!-- let Bootstrap paginate around a big table -->
<nav aria-label="Invoice pages">
<ul class="pagination pagination-sm mb-0">
<li class="page-item disabled"><a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a></li>
<li class="page-item active" aria-current="page"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>Full lesson: Typography, tables, images and content components →
Forms in depth
Validation that reflects the server
<div class="col-md-6">
<label for="slug" class="form-label">Workspace URL</label>
<input type="text" class="form-control" id="slug" name="slug" required
aria-describedby="slugHelp slugError">
<div id="slugHelp" class="form-text">Lowercase letters, numbers and hyphens.</div>
<div id="slugError" class="invalid-feedback">That workspace name is already taken.</div>
</div>
Overlays: tooltips, popovers and toasts
Toasts and stacking
<div class="toast-container position-fixed bottom-0 end-0 p-3" id="toasts"
aria-live="polite" aria-atomic="true"></div>Full lesson: Overlays: tooltips, popovers and toasts →
Accessibility with Bootstrap
Keyboard and reduced motion
// Programmatic focus needs a target that can receive it.
// main has tabindex="-1" in the markup above, so this works:
document.querySelector('#main').focus();
// Announce a change that is not in a live region yet
const status = document.getElementById('toasts');
status.textContent = 'Filters applied. 12 results.';Full lesson: Accessibility with Bootstrap →
Theming with CSS variables, RTL and colour modes
Right-to-left and logical properties
<!-- One attribute flips the whole framework -->
<html lang="ar" dir="rtl" data-bs-theme="light">
<head>
<link rel="stylesheet" href="bootstrap.rtl.min.css">
</head>Full lesson: Theming with CSS variables, RTL and colour modes →
Migrating from Bootstrap 4 and knowing the limits
The breaking changes that matter
# A first pass that finds the worst offenders before you open a browser
grep -rEo 'data-(toggle|target|dismiss|slide|ride|spy|parent)=' src/ | sort | uniq -c
grep -rEo '\b(ml|mr|pl|pr)-[0-5a]' src/ | sort | uniq -c
grep -rnE '\$\(.*\)\.(modal|collapse|tooltip|dropdown|tab)\(' src/
# and a safety net while you migrate
npm install bootstrap@5 bootstrap-iconsFull lesson: Migrating from Bootstrap 4 and knowing the limits →
FAQ
Is this Bootstrap 5 cheat sheet free to use?
Where do the examples come from?
How do I go deeper than a cheat sheet?
Related cheat sheets
HTML CSS JavaScript TypeScript HTML DOM AJAX
Last refreshed 2026-09-27.