Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Dark mode

Since version 5.3 Bootstrap has built-in color modes: light and dark. A mode is turned on with a single data-bs-theme attribute, and all components — cards, tables, forms, menus — recolor themselves. You do not write separate dark theme styles.

A theme for the whole page

The attribute goes on the <html> tag:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
 
<script>document.documentElement.setAttribute('data-bs-theme', 'dark');</script>
 
<div class="card" style="max-width: 18rem">
  <div class="card-body">
    <h5 class="card-title">A dark card</h5>
    <input class="form-control mb-2" placeholder="Task title">
    <button type="button" class="btn btn-primary">Add</button>
  </div>
</div>

The preview has no <html> tag of its own, so a line of JavaScript sets the attribute. In your index.html just write <html lang="en" data-bs-theme="dark">. The page background, the card and the field turned dark, the text light, and the blue button stayed blue.

A theme for one block

The attribute works on any element and applies to everything inside. This way only the header or the admin sidebar can be dark:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
 
<div class="d-flex border">
  <div class="bg-body text-body p-3" data-bs-theme="dark" style="width: 160px">
    <div class="fw-bold mb-2">Tasko</div>
    <div class="text-body-secondary">Overview</div>
    <div class="text-body-secondary">Orders</div>
  </div>
  <div class="bg-body text-body p-3 flex-grow-1">Light main area</div>
</div>

The left menu is dark, the right part is light. The bg-body and text-body classes take the background and text color of the current theme, so the same markup looks right in both themes.

A theme switch

The theme is just an attribute, so a switch changes it from JavaScript:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
 
<div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" role="switch" id="themeSwitch">
  <label class="form-check-label" for="themeSwitch">Dark theme</label>
</div>
 
<script>
  const root = document.documentElement;
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
  const themeSwitch = document.querySelector('#themeSwitch');
 
  root.setAttribute('data-bs-theme', prefersDark ? 'dark' : 'light');
  themeSwitch.checked = prefersDark;
  themeSwitch.addEventListener('change', () => {
    root.setAttribute('data-bs-theme', themeSwitch.checked ? 'dark' : 'light');
  });
</script>

On load the theme matches the operating system setting: matchMedia checks the prefers-color-scheme media query. Click the switch and the preview changes theme. In a real project the user's choice is also saved to localStorage so it survives a reload.

Common mistake

Coloring blocks with bg-white, bg-light, text-dark. These are fixed colors: in dark mode such a block stays white with dark text in the middle of a dark page. For backgrounds and text that should follow the theme, use bg-body, bg-body-tertiary, text-body and text-body-secondary.

Thanks for reading!

Donate to the site — we work hard for you.