Enabling Dark Mode: Bootstrap
Tags: css, beginners
Published: 2023-02-28 18:39:09

Enable the built in dark color mode across your entire project by adding the `data-bs-theme="dark"` attribute to the `<html>` element. This will apply the dark color mode to all components and elements, other than those with a specific `data-bs-theme` attribute applied.

```
<!doctype html>
<html lang="en" data-bs-theme="dark">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello, world!</h1>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
  </body>
</html>
```

To allow visitors or users to toggle color modes, you’ll need to create a toggle element to control the `data-bs-theme` attribute on the root element, `<html>`. We’ve built a toggler in our documentation that initially defers to a user’s current system color mode, but provides an option to override that and pick a specific color mode.

```
(() => {
  'use strict'

  const storedTheme = localStorage.getItem('theme')

  const getPreferredTheme = () => {
    if (storedTheme) {
      return storedTheme
    }

    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
  }

  const setTheme = function (theme) {
    if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.setAttribute('data-bs-theme', 'dark')
    } else {
      document.documentElement.setAttribute('data-bs-theme', theme)
    }
  }

  setTheme(getPreferredTheme())

  const showActiveTheme = theme => {
    const activeThemeIcon = document.querySelector('.theme-icon-active use')
    const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
    const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')

    document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
      element.classList.remove('active')
    })

    btnToActive.classList.add('active')
    activeThemeIcon.setAttribute('href', svgOfActiveBtn)
  }

  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
    if (storedTheme !== 'light' || storedTheme !== 'dark') {
      setTheme(getPreferredTheme())
    }
  })

  window.addEventListener('DOMContentLoaded', () => {
    showActiveTheme(getPreferredTheme())

    document.querySelectorAll('[data-bs-theme-value]')
      .forEach(toggle => {
        toggle.addEventListener('click', () => {
          const theme = toggle.getAttribute('data-bs-theme-value')
          localStorage.setItem('theme', theme)
          setTheme(theme)
          showActiveTheme(theme)
        })
      })
  })
})()
```

Dozens of root level CSS variables are repeated as overrides for dark mode. These are scoped to the color mode selector, which defaults to `data-bs-theme` but can be configured to use a prefers-color-scheme media query. Use these variables as a guideline for generating your own new color modes.

```
    --#{$prefix}body-color: #{$body-color-dark};
    --#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};
    --#{$prefix}body-bg: #{$body-bg-dark};
    --#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};

    --#{$prefix}emphasis-color: #{$body-emphasis-color-dark};
    --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};

    --#{$prefix}secondary-color: #{$body-secondary-color-dark};
    --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
    --#{$prefix}secondary-bg: #{$body-secondary-bg-dark};
    --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};

    --#{$prefix}tertiary-color: #{$body-tertiary-color-dark};
    --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
    --#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};
    --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};

    --#{$prefix}emphasis-color: #{$emphasis-color-dark};

    --#{$prefix}primary-text: #{$primary-text-dark};
    --#{$prefix}secondary-text: #{$secondary-text-dark};
    --#{$prefix}success-text: #{$success-text-dark};
    --#{$prefix}info-text: #{$info-text-dark};
    --#{$prefix}warning-text: #{$warning-text-dark};
    --#{$prefix}danger-text: #{$danger-text-dark};
    --#{$prefix}light-text: #{$light-text-dark};
    --#{$prefix}dark-text: #{$dark-text-dark};

    --#{$prefix}primary-bg-subtle: #{$primary-bg-subtle-dark};
    --#{$prefix}secondary-bg-subtle: #{$secondary-bg-subtle-dark};
    --#{$prefix}success-bg-subtle: #{$success-bg-subtle-dark};
    --#{$prefix}info-bg-subtle: #{$info-bg-subtle-dark};
    --#{$prefix}warning-bg-subtle: #{$warning-bg-subtle-dark};
    --#{$prefix}danger-bg-subtle: #{$danger-bg-subtle-dark};
    --#{$prefix}light-bg-subtle: #{$light-bg-subtle-dark};
    --#{$prefix}dark-bg-subtle: #{$dark-bg-subtle-dark};

    --#{$prefix}primary-border-subtle: #{$primary-border-subtle-dark};
    --#{$prefix}secondary-border-subtle: #{$secondary-border-subtle-dark};
    --#{$prefix}success-border-subtle: #{$success-border-subtle-dark};
    --#{$prefix}info-border-subtle: #{$info-border-subtle-dark};
    --#{$prefix}warning-border-subtle: #{$warning-border-subtle-dark};
    --#{$prefix}danger-border-subtle: #{$danger-border-subtle-dark};
    --#{$prefix}light-border-subtle: #{$light-border-subtle-dark};
    --#{$prefix}dark-border-subtle: #{$dark-border-subtle-dark};

    --#{$prefix}heading-color: #{$headings-color-dark};

    --#{$prefix}link-color: #{$link-color-dark};
    --#{$prefix}link-hover-color: #{$link-hover-color-dark};
    --#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};
    --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};

    --#{$prefix}code-color: #{$code-color-dark};

    --#{$prefix}border-color: #{$border-color-dark};
    --#{$prefix}border-color-translucent: #{$border-color-translucent-dark};
    
```

Happy coding!