Theme Bootstrap 5 with CSS Variables—No Sass Needed
Want to change Bootstrap 5’s colors and spacing without a build step? Use its CSS custom properties. Override the root variables for a site‑wide theme or target specific components for local tweaks. This guide walks through the process, shows a live example, and explains the limits of the approach.
30 Jun 2026, 00:56 UTC

Problem: Theme Bootstrap Without a Build Tool
When you start a project with Bootstrap 5 you often want to adjust its color palette, font stack, or spacing. The traditional route is to copy the source Sass files, edit the maps, and recompile. That adds a build step and forces you to keep the Sass source in sync. For quick prototypes, small sites, or static pages, a CSS‑only solution is preferable.
Thesis: Bootstrap 5 Exposes Design Tokens as CSS Variables
Bootstrap 5 ships with a set of root‑level CSS custom properties (variables) that map to its design tokens: --bs-primary, --bs-font-family-sans-serif, --bs-border-radius, and many more. Every component’s styles reference these variables, so changing a variable value instantly updates every instance of that component. Because the variables live in plain CSS, you can modify them in a stylesheet, inline, or even via JavaScript—no Sass compilation required.
Section 1 – Overriding Root Variables for a Site‑Wide Theme
To apply a global theme, place your overrides under the :root selector. The following snippet changes the primary color and the default font family:
/* style.css */
:root {
/* Primary brand color */
--bs-primary: #ff6600;
/* Override the default sans‑serif stack */
--bs-font-family-sans-serif: "Open Sans", sans-serif;
}
Include style.css after the Bootstrap CSS link:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
When the page loads, every component that uses --bs-primary (buttons, links, alerts) will render in orange, and text will use Open Sans. You can verify this by opening the browser devtools, inspecting a button, and seeing the computed color change.
Section 2 – Scoping Overrides to a Sub‑Tree
Sometimes you want a different theme inside a modal or a sidebar. CSS variables are inherited, but you can override them on any element. The following example creates a light‑background theme for a specific div:
/* style.css */
.theme‑override {
--bs-body-bg: #f8f9fa; /* light gray */
--bs-primary: #0066cc; /* blue */
}
And the markup:
<div class="theme‑override p-4">
<h1>Local Theme</h1>
<button class="btn btn-primary">Primary Button</button>
</div>
Only the elements inside .theme‑override inherit the new values; the rest of the page remains unchanged. This technique is handy for creating dark‑mode panels, theming third‑party widgets, or testing variations.
Section 3 – Practical Example: Live Theming with JavaScript
Because the variables are part of the DOM’s style system, you can toggle them at runtime. Below is a minimal script that switches the primary color when a button is clicked:
<button id="toggle-theme" class="btn btn-secondary mb-3">Toggle Theme</button>
<script>
const toggle = document.getElementById('toggle-theme');
let dark = false;
toggle.addEventListener('click', () => {
dark = !dark;
document.documentElement.style.setProperty(
'--bs-primary', dark ? '#222' : '#ff6600'
);
});
</script>
When the button is pressed, the --bs-primary variable on document.documentElement (the html element) changes, and all components that reference it update immediately.
Section 4 – Trade‑offs and Limitations
- Bootstrap 5 only – CSS variable support was added in v5; earlier releases rely on Sass maps and cannot use this method.
- Limited to exposed tokens – Bootstrap’s Sass utilities (e.g.,
map-get,loop) are not available through CSS variables. If you need custom utilities, you’ll still need to compile Sass. - Browser support – All modern browsers support CSS variables, but older browsers (IE 11 and below) do not. If you target those browsers, a fallback strategy is required.
- Performance – Overriding many variables on a large DOM can cause re‑paint work, but the impact is negligible for typical sites.
Section 5 – Actionable Checklist for Your Project
- Include Bootstrap 5 CSS from a CDN or local file.
- Create a
theme.cssfile that defines:rootoverrides for site‑wide tokens. - Optionally, add component‑level overrides (e.g.,
.dark-mode { --bs-body-bg: #222; }). Keep these in the same file or a separatecomponents.css. - Load
theme.cssafter Bootstrap’s CSS so your values take precedence. - Test in devtools: change a variable in the
Stylespane and confirm components update. - For dynamic theming, use
element.style.setPropertyin JavaScript. - Validate that the changes persist after a page reload by ensuring the overrides are in a persisted stylesheet.
By following these steps you can achieve a fully themed Bootstrap 5 site without touching Sass, enabling rapid iteration and easier maintenance for static sites, CMS themes, or prototyping environments.
Conclusion
Bootstrap 5’s CSS custom properties turn the framework into a living style sheet. They let you swap colors, fonts, and spacing on the fly, scope themes to specific sections, and even toggle themes at runtime—all without a build step. The trade‑offs are minimal: you’re limited to the exposed tokens and need to avoid older browsers. For most projects, especially those that value speed and simplicity, CSS‑based theming is the pragmatic choice.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.