Color Modes (Dark Mode)
Before Bootstrap 5.3, adding a dark mode to a site like TrailMap meant writing a whole parallel set of overrides — a dark background here, a lighter text color there, checking every component by hand. Bootstrap 5.3 added a built-in color mode system instead: set one attribute, and every component's colors — buttons, cards, forms, navbars, borders — switch to a matching dark palette automatically, because they were never hardcoded colors to begin with. They're CSS custom properties that Bootstrap redefines per mode.
The data-bs-theme Attribute
Add data-bs-theme="dark" to the <html> element and the entire
TrailMap page re-themes instantly — no JavaScript required for the theming itself, no
duplicate stylesheet, no page reload:
<html lang="en" data-bs-theme="dark">
...
</html>
Remove the attribute, or set it to "light", and TrailMap goes back to its normal
palette. Every component already ships CSS rules scoped to
[data-bs-theme="dark"], so this single attribute is the entire mechanism.
What Bootstrap Redefines Under the Hood
Bootstrap's components don't reference literal colors like #fff in their CSS —
they reference CSS variables such as --bs-body-bg and
--bs-body-color. Switching data-bs-theme just points those variables
at different values:
[data-bs-theme="dark"] {
--bs-body-color: #dee2e6;
--bs-body-bg: #212529;
--bs-border-color: #495057;
/* ...and dozens more, per component */
}
Because a card's border, a button's text, and a navbar's background all read from these same shared variables rather than fixed values, one attribute change cascades correctly through every component TrailMap uses, including ones added later in the project without any extra dark-mode work.
Worked Example: A TrailMap Dark Mode Toggle
A real toggle needs a small bit of plain JavaScript to flip the attribute and remember the choice — Bootstrap doesn't ship a toggle button itself, only the CSS mechanism it flips:
<button id="themeToggle" class="btn btn-outline-secondary" type="button">
<i class="bi bi-moon-stars"></i> Toggle Dark Mode
</button>
const toggle = document.getElementById('themeToggle');
const html = document.documentElement;
// restore a saved preference on page load
const saved = localStorage.getItem('trailmap-theme');
if (saved) html.setAttribute('data-bs-theme', saved);
toggle.addEventListener('click', function() {
const current = html.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark';
html.setAttribute('data-bs-theme', current);
localStorage.setItem('trailmap-theme', current);
});
Scoping a Color Mode to One Section
data-bs-theme isn't limited to <html>. Setting it on any
container re-themes just that container, which is handy for a permanently-dark TrailMap
sidebar sitting inside an otherwise light page:
<div class="p-3" data-bs-theme="dark">
<div class="card">
<div class="card-body">Saved Trails</div>
</div>
</div>