Skip to content

Bootstrap Themes

Bootstrap 5.3 introduced a native color mode system for light and dark themes. This lesson covers how to enable, customize, and extend Bootstrap's theming support.

Bootstrap Themes Overview

Setting data-bs-theme="dark" on the <html> element (or any container) switches a set of CSS custom properties to their dark-mode values, automatically adjusting background colors, text colors, borders, and component styling across the whole page or just that scoped section.

Beyond the built-in light and dark modes, you can define your own custom theme by combining Sass variable overrides for the base palette with additional CSS variable overrides scoped to a custom data-bs-theme value, letting users switch between more than just two themes.

Concept Description Common Usage
data-bs-theme="light"/"dark" Built-in color mode switch Toggling the whole page or a section's theme
Color mode CSS variables Root variables that change per theme Backgrounds, text, and border colors adapting automatically
Scoped theming data-bs-theme on a nested container Mixing themes within one page, like a dark sidebar
JavaScript theme persistence Storing preference in localStorage Remembering a user's chosen theme across visits
Custom named themes Extending beyond light/dark with your own values Multi-brand or multi-tenant theming

Bootstrap Themes Example

<html lang="en" data-bs-theme="light">
  ...
  <div class="card" data-bs-theme="dark">
    <div class="card-body">This card renders in dark mode even though the page is light.</div>
  </div>
</html>

<script>
  const stored = localStorage.getItem("theme") || "light";
  document.documentElement.setAttribute("data-bs-theme", stored);

  function setTheme(theme) {
    document.documentElement.setAttribute("data-bs-theme", theme);
    localStorage.setItem("theme", theme);
  }
</script>

The outer html element sets the page-wide theme to light, while the nested card explicitly overrides it to dark, showing that data-bs-theme can be scoped to any container, not just the root. The script demonstrates a common persistence pattern: reading a saved preference from localStorage on load and providing a setTheme function to update and remember the user's choice.

Top 10 Bootstrap Themes Examples

These are the theming patterns you'll use to support light, dark, and custom color modes.

# Example Syntax
1 Enable light theme <html data-bs-theme="light">
2 Enable dark theme <html data-bs-theme="dark">
3 Scoped dark section <div data-bs-theme="dark" class="p-4">...</div>
4 Read current theme in JS document.documentElement.getAttribute('data-bs-theme')
5 Set theme in JS document.documentElement.setAttribute('data-bs-theme', 'dark');
6 Persist theme in localStorage localStorage.setItem('theme', 'dark');
7 Theme toggle button <button onclick="toggleTheme()">Toggle Theme</button>
8 Respect OS preference window.matchMedia('(prefers-color-scheme: dark)').matches
9 Override a variable per theme [data-bs-theme="dark"] { --bs-body-bg: #0f172a; }
10 Custom named theme attribute <html data-bs-theme="brand-dark">

Best Practices

  • Read the user's saved theme preference before first paint to avoid a flash of the wrong theme.
  • Respect prefers-color-scheme as a sensible default when no explicit preference is stored yet.
  • Scope data-bs-theme to specific containers when only part of the page needs a different mode.
  • Test every custom component and color override in both light and dark modes.
  • Provide a visible, easy-to-find control for switching themes rather than hiding it deep in settings.
  • Keep custom theme names descriptive if you go beyond simple light/dark, like brand-dark or high-contrast.
  • Verify color contrast ratios independently for each theme you support.

Common Mistakes

  • Setting the theme only after the page renders, causing a visible flash of the default theme.
  • Forgetting to test custom components and colors specifically in dark mode.
  • Not persisting the user's theme choice, forcing them to reselect it on every visit.
  • Assuming data-bs-theme only works on the html element, when it can be scoped anywhere.
  • Overriding colors with hardcoded hex values instead of theme-aware CSS variables, breaking dark mode.
  • Ignoring prefers-color-scheme entirely and forcing a single default theme on all new visitors.

Key Takeaways

  • data-bs-theme enables Bootstrap's built-in light and dark color modes.
  • The attribute can be scoped to the whole page or to individual containers.
  • JavaScript and localStorage together provide persistent, user-controlled theme switching.
  • Custom themes can extend beyond light/dark by defining your own data-bs-theme values.
  • Testing color contrast and component appearance across every supported theme is essential.

Pro Tip

Set the initial data-bs-theme attribute in an inline script placed in the document head, before any CSS loads, so returning visitors see their chosen theme immediately instead of a brief flash of the default.