メインコンテンツにスキップ ドキュメントナビゲーションにスキップ

カラーモード(Color modes) v5.3.0新設

Bootstrapは、v5.3.0からカラーモード、つまりテーマに対応するようになった。デフォルトのライトカラーモードと新しいダークモード、またはテンプレートを使って独自のカラーモードを作成してみて下さい。

※"v5.3.0"での変更はv5.3.0-alpha版での変更も含みます。

ダークモード(Dark mode)

Bootstrapがカラーモードに対応し、まずはダークモードについて。v5.3.0では独自のカラーモードの切替を実装することができ(Bootstrapの解説の例は以下を参照)、様々なカラーモードを自由に適用できる。ライトモード(デフォルト)とダークモードをサポートしている。カラーモードは、data-bs-theme 属性のおかげで <html> 要素でグローバルや特定のコンポーネントや要素で切り替えられる。

また、カラーモードミックスインを使えば、メディアクエリによる実装に切り替えられる。詳細については使用方法の項目に記載。ただし、この場合は以下のようにコンポーネント単位でテーマを変更することはできないので注意。

実例(Example)

例えばドロップダウンメニューのカラーモードを変更するには、親要素の .dropdowndata-bs-theme="light"data-bs-theme="dark" を追加する。これでグローバルなカラーモードに関係なく、これらのドロップダウンは指定されたテーマ値で表示されるようになる。

見本
設定例
ライト(標準)モード<div class="dropdown" data-bs-theme="light">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonLight" data-bs-toggle="dropdown" aria-expanded="false">
    デフォルトのドロップダウン
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonLight">
    <li><a class="dropdown-item active" href="#" aria-current="true">メニュー1</a></li>
    <li><a class="dropdown-item" href="#">メニュー2</a></li>
    <li><a class="dropdown-item" href="#">メニュー3</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">その他リンク</a></li>
  </ul>
</div>
ダークモード<div class="dropdown" data-bs-theme="dark">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonDark" data-bs-toggle="dropdown" aria-expanded="false">
    ダークのドロップダウン
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonDark">
    <li><a class="dropdown-item active" href="#" aria-current="true">メニュー1</a></li>
    <li><a class="dropdown-item" href="#">メニュー2</a></li>
    <li><a class="dropdown-item" href="#">メニュー3</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">その他リンク</a></li>
  </ul>
</div>

※カラーモードによる見え方の違い ★はカラーモードによって色が異なる

ライトモード

標準カラー

文字色 .text-body
背景色 .bg-body
罫線色 .border
リンクの色 <a>
コードの色 <code>

二次Bodyカラー

文字色 .text-body-secondary
背景色 .bg-body-secondary

三次Bodyカラー

文字色 .text-body-tertiary
背景色 .bg-body-tertiary

強調文字カラー

文字色 .text-body-emphasis

Primaryテーマカラー

文字色 .text-primary
背景色 .bg-primary
文字&背景色 .text-bg-primary

淡いPrimaryテーマカラー

文字色 .text-primary-emphasis
背景色 .bg-primary-subtle
罫線色 .border-primary-subtle

Secondaryテーマカラー

文字色 .text-secondary
背景色 .bg-secondary
文字&背景色 .text-bg-secondary

淡いSecondaryテーマカラー

文字色 .text-secondary-emphasis
背景色 .bg-secondary-subtle
罫線色 .border-secondary-subtle

Successテーマカラー

文字色 .text-success
背景色 .bg-success
文字&背景色 .text-bg-success

淡いSuccessテーマカラー

文字色 .text-success-emphasis
背景色 .bg-success-subtle
罫線色 .border-success-subtle

Dangerテーマカラー

文字色 .text-danger
背景色 .bg-danger
文字&背景色 .text-bg-danger

淡いDangerテーマカラー

文字色 .text-danger-emphasis
背景色 .bg-danger-subtle
罫線色 .border-danger-subtle

Warningテーマカラー

文字色 .text-warning
背景色 .bg-warning
文字&背景色 .text-bg-warning

淡いWarningテーマカラー

文字色 .text-warning-emphasis
背景色 .bg-warning-subtle
罫線色 .border-warning-subtle

Infoテーマカラー

文字色 .text-info
背景色 .bg-info
文字&背景色 .text-bg-info

淡いInfoテーマカラー

文字色 .text-info-emphasis
背景色 .bg-info-subtle
罫線色 .border-info-subtle

Lightテーマカラー

文字色 .text-light
背景色 .bg-light
文字&背景色 .text-bg-light

淡いLightテーマカラー

文字色 .text-light-emphasis
背景色 .bg-light-subtle
罫線色 .border-light-subtle

Darkテーマカラー

文字色 .text-dark
背景色 .bg-dark
文字&背景色 .text-bg-dark

淡いDarkテーマカラー

文字色 .text-dark-emphasis
背景色 .bg-dark-subtle
罫線色 .border-dark-subtle

Blackカラー

文字色 .text-black
背景色 .bg-black

Whiteカラー

文字色 .text-white
背景色 .bg-white
ダークモード

標準カラー

文字色 .text-body
背景色 .bg-body
罫線色 .border
リンクの色 <a>
コードの色 <code>

二次Bodyカラー

文字色 .text-body-secondary
背景色 .bg-body-secondary

三次Bodyカラー

文字色 .text-body-tertiary
背景色 .bg-body-tertiary

強調文字カラー

文字色 .text-body-emphasis

Primaryテーマカラー

文字色 .text-primary
背景色 .bg-primary
文字&背景色 .text-bg-primary

淡いPrimaryテーマカラー

文字色 .text-primary-emphasis
背景色 .bg-primary-subtle
罫線色 .border-primary-subtle

Secondaryテーマカラー

文字色 .text-secondary
背景色 .bg-secondary
文字&背景色 .text-bg-secondary

淡いSecondaryテーマカラー

文字色 .text-secondary-emphasis
背景色 .bg-secondary-subtle
罫線色 .border-secondary-subtle

Successテーマカラー

文字色 .text-success
背景色 .bg-success
文字&背景色 .text-bg-success

淡いSuccessテーマカラー

文字色 .text-success-emphasis
背景色 .bg-success-subtle
罫線色 .border-success-subtle

Dangerテーマカラー

文字色 .text-danger
背景色 .bg-danger
文字&背景色 .text-bg-danger

淡いDangerテーマカラー

文字色 .text-danger-emphasis
背景色 .bg-danger-subtle
罫線色 .border-danger-subtle

Warningテーマカラー

文字色 .text-warning
背景色 .bg-warning
文字&背景色 .text-bg-warning

淡いWarningテーマカラー

文字色 .text-warning-emphasis
背景色 .bg-warning-subtle
罫線色 .border-warning-subtle

Infoテーマカラー

文字色 .text-info
背景色 .bg-info
文字&背景色 .text-bg-info

淡いInfoテーマカラー

文字色 .text-info-emphasis
背景色 .bg-info-subtle
罫線色 .border-info-subtle

Lightテーマカラー

文字色 .text-light
背景色 .bg-light
文字&背景色 .text-bg-light

淡いLightテーマカラー

文字色 .text-light-emphasis
背景色 .bg-light-subtle
罫線色 .border-light-subtle

Darkテーマカラー

文字色 .text-dark
背景色 .bg-dark
文字&背景色 .text-bg-dark

淡いDarkテーマカラー

文字色 .text-dark-emphasis
背景色 .bg-dark-subtle
罫線色 .border-dark-subtle

Blackカラー

文字色 .text-black
背景色 .bg-black

Whiteカラー

文字色 .text-white
背景色 .bg-white

使い方(How it works)

  • 上記のように、カラーモードスタイルは data-bs-theme 属性によって制御される。この属性は <html> 要素や他の要素やBootstrapコンポーネントに適用できる。もし <html> 要素に適用すれば全体に適用され、コンポーネントや要素に適用した場合は、その特定のコンポーネントや要素に適用される。
  • サポートしたい各カラーモードについて、共有のグローバルCSS変数を新しく再定義する必要がある。この作業はすでに _root.scss スタイルシートでダークモード用に行っており、ライトモードはデフォルト値になっている。カラーモード固有のスタイルを記述する場合はミックスインを使用:
    // scss/_root.scssのカラーモード変数
    @include color-mode(dark) {
      // CSS変数の再定義はこちら...
    }
  • ダークモード用の共有グローバルCSS変数の再定義を行うため、カスタムの _variables-dark.scss を使用。このファイルは独自のカラーモードには必要ないが、Bootstrapのダークモードには2つの理由で必要。まずはグローバルカラーをリセットする場所を1つにし、次にアコーディオンやフォームコンポーネントなどのCSSに埋め込まれている背景画像用に、いくつかのSass変数を再定義する必要があったため。

使用方法(Usage)

ダークモードを有効にする(Enable dark mode)

<html> 要素に data-bs-theme="dark" 属性を追加して、プロジェクト全体で組み込みのダークカラーモードを有効にする。これにより、特定の data-bs-theme 属性が適用されているものを除いてすべてのコンポーネントと要素にダークカラーモードが適用される。
クイックスタート・テンプレートに基づいた構築:

設定例
<!doctype html>
<html lang="ja" data-bs-theme="dark">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrapのデモ</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  </head>
  <body>
    <h1>ようこそ!</h1>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </body>
</html>

Bootstrapにはまだカラーモードピッカーは組み込まれていないが、希望があれば、このサイトと同様のものを使用できる。詳細はJavaScriptの項目に記載。

Sassを使用した構築(Building with Sass)

新ダークモードオプションはBootstrapのすべてのユーザが使用できるが、メディアクエリの代わりにデータ属性を経由して制御され、プロジェクトのカラーモードは自動的に切り替わらない。Sassで $enable-dark-modefalse に変更すれば、ダークモードを完全に無効にできる。

カラーモードの適用方法を制御するには、カスタムSassミックスインである color-mode() を使用。デフォルトでは、data 属性のアプローチを使用しており、サイト訪問者が自動的なダークモードを選択したり、好みをコントロールできるような、(Bootstrapのドキュメントのように)よりユーザーフレンドリーな体験を作ることができる。また、この方法は、様々なテーマやライトとダーク以外のカスタムカラーモードを追加するための簡単で拡張性のある方法。

メディアクエリを使用して、カラーモードのみを自動化したい場合は、Sass変数でミックスインのデフォルトタイプを変更できる。以下でスニペットとそのコンパイルされたCSSの出力を見てみる。

Sass$color-mode-type: data;

@include color-mode(dark) {
  .element {
    color: var(--bs-primary-text-emphasis);
    background-color: var(--bs-primary-bg-subtle);
  }
}

出力後:

CSS[data-bs-theme=dark] .element {
  color: var(--bs-primary-text-emphasis);
  background-color: var(--bs-primary-bg-subtle);
}

また media-query に設定した場合。

Sass$color-mode-type: media-query;

@include color-mode(dark) {
  .element {
    color: var(--bs-primary-text-emphasis);
    background-color: var(--bs-primary-bg-subtle);
  }
}

出力後:

CSS@media (prefers-color-scheme: dark) {
  .element {
    color: var(--bs-primary-text-emphasis);
    background-color: var(--bs-primary-bg-subtle);
  }
}

カスタムカラーモード(Custom color modes)

カラーモードの主な使用例はライトモードとダークモードだが、カスタムのカラーモードも可能。カラーモードの名前としてカスタム値を指定して、独自の data-bs-theme セレクタを作成し、必要に応じてSassとCSSの変数を変更する。Bootstrapではダークモード専用のSass変数を格納するために、別途 _variables-dark.scss スタイルシートを作成することにしたが、これは使用者にとって必要なことではない。

例えば data-bs-theme="blue" セレクタで"青いテーマ"が作成できる。カスタムのSassかCSSファイルに新しいセレクタを追加し、必要に応じてグローバルかコンポーネントCSS変数を再定義する。Sassを使用すれば、再定義したCSS変数内でSassの関数を使用もできる。

Sass[data-bs-theme="blue"] {
  --bs-body-color: var(--bs-white);
  --bs-body-color-rgb: #{to-rgb($white)};
  --bs-body-bg: var(--bs-blue);
  --bs-body-bg-rgb: #{to-rgb($blue)};
  --bs-tertiary-bg: #{$blue-600};

  .dropdown-menu {
    --bs-dropdown-bg: #{mix($blue-500, $blue-600)};
    --bs-dropdown-link-active-bg: #{$blue-700};
  }

  .btn-secondary {
    --bs-btn-bg: #{mix($gray-600, $blue-400, .5)};
    --bs-btn-border-color: #{rgba($white, .25)};
    --bs-btn-hover-bg: #{darken(mix($gray-600, $blue-400, .5), 5%)};
    --bs-btn-hover-border-color: #{rgba($white, .25)};
    --bs-btn-active-bg: #{darken(mix($gray-600, $blue-400, .5), 10%)};
    --bs-btn-active-border-color: #{rgba($white, .5)};
    --bs-btn-focus-border-color: #{rgba($white, .5)};
    --bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .2);
  }
}
見本
青いテーマの実例

青いテーマがどのように見えるかを、文章で表現したもの。


設定例
<div data-bs-theme="blue">
  ...
</div>

JavaScript

サイト訪問者やユーザーがカラーモードを切り替えられるようにするには、ルート要素である <html>data-bs-theme 属性を制御するための切替え要素を作成する必要がある。本サイトでは、最初はユーザーの現在のシステムのカラーモードに従うが、それを上書きして特定のカラーモードを選択するオプションを提供する切替ボタンを作成している。

ここでは、その動力源となるJavaScriptを紹介。BootstrapのコンポーネントのHTMLとCSSを使ってどのように実装されているか、本サイトのナビバーで自由に切り替えて調べてみて下さい。サイトの再読み込み時に画面がちらつく可能性があるため、JavaScriptをページ上部に記述することを推奨。なおカラーモードにメディアクエリを使用する場合、暗黙的な制御を好むならJavaScriptの修正や削除をする必要があるかもしれない。

v5.3.3更新

color-modes.js/*!
 * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
 * Copyright 2011-2024 The Bootstrap Authors
 * Licensed under the Creative Commons Attribution 3.0 Unported License.
 */

(() => {
  'use strict'

  const getStoredTheme = () => localStorage.getItem('theme')
  const setStoredTheme = theme => localStorage.setItem('theme', theme)

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

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

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

  setTheme(getPreferredTheme())

  const showActiveTheme = (theme, focus = false) => {
    const themeSwitcher = document.querySelector('#bd-theme')

    if (!themeSwitcher) {
      return
    }

    const themeSwitcherText = document.querySelector('#bd-theme-text')
    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')
      element.setAttribute('aria-pressed', 'false')
    })

    btnToActive.classList.add('active')
    btnToActive.setAttribute('aria-pressed', 'true')
    activeThemeIcon.setAttribute('href', svgOfActiveBtn)
    const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
    themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)

    if (focus) {
      themeSwitcher.focus()
    }
  }

  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
    const storedTheme = getStoredTheme()
    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')
          setStoredTheme(theme)
          setTheme(theme)
          showActiveTheme(theme, true)
        })
      })
  })
})()

color-modes.js を使用したカラーモードの切替(ドロップダウンボタンの動作については本サイトの実例の各ページにあるカラーモード切替ボタンでご確認下さい):

設定例
HTML<!doctype html>
<html lang="ja" data-bs-theme="auto">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>カラーモード切替のデモ</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <script src="js/color-modes.js"></script>
  </head>
  <body>
    <!-- アイコンの設定 -->
    <svg xmlns="http://www.w3.org/2000/svg" class="d-none">
      <symbol id="circle-half" viewBox="0 0 16 16">
        <path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"/>
      </symbol>
      <symbol id="moon-stars-fill" viewBox="0 0 16 16">
        <path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
        <path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z"/>
      </symbol>
      <symbol id="sun-fill" viewBox="0 0 16 16">
        <path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
      </symbol>
    </svg>

    <h1>カラーモードの切替</h1>
    <p>適宜カラーモードを切り替えて下さい。</p>
    <!-- ドロップダウンボタン -->
    <div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle">
      <button class="btn btn-bd-primary py-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" aria-label="テーマの切替(ダーク)">
        <svg class="bi my-1 theme-icon-active" width="1em" height="1em"><use href="#moon-stars-fill"></use></svg>
        <span class="visually-hidden" id="bd-theme-text">カラーモードの切替</span>
      </button>
      <ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="bd-theme-text">
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
            <svg class="bi me-2 opacity-50 theme-icon" width="1em" height="1em"><use href="#sun-fill"></use></svg>
            ライト
            <svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="dark" aria-pressed="true">
            <svg class="bi me-2 opacity-50 theme-icon" width="1em" height="1em"><use href="#moon-stars-fill"></use></svg>
            ダーク
            <svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="auto" aria-pressed="false">
            <svg class="bi me-2 opacity-50 theme-icon" width="1em" height="1em"><use href="#circle-half"></use></svg>
            オート
            <svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
          </button>
        </li>
      </ul>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </body>
</html>
CSS/* カラーモード切替ボタン */
.btn-bd-primary {
  --bd-violet-bg: #712cf9;
  --bd-violet-rgb: 112.520718, 44.062154, 249.437846;

  --bs-btn-font-weight: 600;
  --bs-btn-color: var(--bs-white);
  --bs-btn-bg: var(--bd-violet-bg);
  --bs-btn-border-color: var(--bd-violet-bg);
  --bs-btn-hover-color: var(--bs-white);
  --bs-btn-hover-bg: #6528e0;
  --bs-btn-hover-border-color: #6528e0;
  --bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
  --bs-btn-active-color: var(--bs-btn-hover-color);
  --bs-btn-active-bg: #5a23c8;
  --bs-btn-active-border-color: #5a23c8;
}
.bd-mode-toggle {
  z-index: 1500;
}

テーマカラーを追加(Adding theme colors)

アラートやリストグループのような一部のコンポーネントでは、$theme-colors に新しい色を追加するだけでは十分ではない。新しい色はライトテーマ用の $theme-colors-text, $theme-colors-bg-subtle, $theme-colors-border-subtle にも定義する必要があり、ダークテーマ用の $theme-colors-text-dark, $theme-colors-bg-subtle-dark, $theme-colors-border-subtle-dark にも定義が必要。

Sassは既存の変数やマップから独自のSass変数を生成することができないため、これは手作業になる。Bootstrapの将来のバージョンでは、重複を減らすためにこの設定を見直す予定。

設定例
custom.scss// 必須
@import "functions";
@import "variables";
@import "variables-dark";

// カスタムカラーを $theme-colors に追加
$custom-colors: (
  "custom-color": #712cf9
);
$theme-colors: map-merge($theme-colors, $custom-colors);

@import "maps";
@import "mixins";
@import "utilities";

// 新しいテーママップにカスタムカラーを追加

// ライトモード
$custom-colors-text: ("custom-color": #712cf9);
$custom-colors-bg-subtle: ("custom-color": #e1d2fe);
$custom-colors-border-subtle: ("custom-color": #bfa1fc);

$theme-colors-text: map-merge($theme-colors-text, $custom-colors-text);
$theme-colors-bg-subtle: map-merge($theme-colors-bg-subtle, $custom-colors-bg-subtle);
$theme-colors-border-subtle: map-merge($theme-colors-border-subtle, $custom-colors-border-subtle);

// ダークモード
$custom-colors-text-dark: ("custom-color": #e1d2f2);
$custom-colors-bg-subtle-dark: ("custom-color": #8951fa);
$custom-colors-border-subtle-dark: ("custom-color": #e1d2f2);

$theme-colors-text-dark: map-merge($theme-colors-text-dark, $custom-colors-text-dark);
$theme-colors-bg-subtle-dark: map-merge($theme-colors-bg-subtle-dark, $custom-colors-bg-subtle-dark);
$theme-colors-border-subtle-dark: map-merge($theme-colors-border-subtle-dark, $custom-colors-border-subtle-dark);

// 残りのBootstrapのインポート
@import "root";
@import "reboot";
// その他

CSS

CSS変数(Variables)

ダークモードの再定義として、ルートレベルのCSS変数が何十個も繰り返される。これらはカラーモードセレクタに範囲設定されており、デフォルトは data-bs-theme だが、prefers-color-scheme メディアクエリを使用するように設定できる。これらの変数は、独自の新しいカラーモードを生成するためのガイドラインとしてご使用下さい。

デフォルトの設定
scss/_root.scss 内 root-dark-mode-vars の設定--#{$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)};

@each $color, $value in $theme-colors-text-dark {
  --#{$prefix}#{$color}-text-emphasis: #{$value};
}

@each $color, $value in $theme-colors-bg-subtle-dark {
  --#{$prefix}#{$color}-bg-subtle: #{$value};
}

@each $color, $value in $theme-colors-border-subtle-dark {
  --#{$prefix}#{$color}-border-subtle: #{$value};
}

--#{$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};

--#{$prefix}form-valid-color: #{$form-valid-color-dark};
--#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};
--#{$prefix}form-invalid-color: #{$form-invalid-color-dark};
--#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};

Sass変数(Sass variables)

ダークカラーモード用のCSS変数は、_variables-dark.scss にあるダークモード専用のSass変数から部分的に生成される。またコンポーネント全体に使用されている埋め込みSVGの色を変更するため、いくつかのカスタム再定義も組み込まれている。

デフォルトの設定
scss/_variables-dark.scss 内 sass-dark-mode-vars の設定$primary-text-emphasis-dark:        tint-color($primary, 40%);
$secondary-text-emphasis-dark:      tint-color($secondary, 40%);
$success-text-emphasis-dark:        tint-color($success, 40%);
$info-text-emphasis-dark:           tint-color($info, 40%);
$warning-text-emphasis-dark:        tint-color($warning, 40%);
$danger-text-emphasis-dark:         tint-color($danger, 40%);
$light-text-emphasis-dark:          $gray-100;
$dark-text-emphasis-dark:           $gray-300;

$primary-bg-subtle-dark:            shade-color($primary, 80%);
$secondary-bg-subtle-dark:          shade-color($secondary, 80%);
$success-bg-subtle-dark:            shade-color($success, 80%);
$info-bg-subtle-dark:               shade-color($info, 80%);
$warning-bg-subtle-dark:            shade-color($warning, 80%);
$danger-bg-subtle-dark:             shade-color($danger, 80%);
$light-bg-subtle-dark:              $gray-800;
$dark-bg-subtle-dark:               mix($gray-800, $black);

$primary-border-subtle-dark:        shade-color($primary, 40%);
$secondary-border-subtle-dark:      shade-color($secondary, 40%);
$success-border-subtle-dark:        shade-color($success, 40%);
$info-border-subtle-dark:           shade-color($info, 40%);
$warning-border-subtle-dark:        shade-color($warning, 40%);
$danger-border-subtle-dark:         shade-color($danger, 40%);
$light-border-subtle-dark:          $gray-700;
$dark-border-subtle-dark:           $gray-800;

$body-color-dark:                   $gray-300;
$body-bg-dark:                      $gray-900;
$body-secondary-color-dark:         rgba($body-color-dark, .75);
$body-secondary-bg-dark:            $gray-800;
$body-tertiary-color-dark:          rgba($body-color-dark, .5);
$body-tertiary-bg-dark:             mix($gray-800, $gray-900, 50%);
$body-emphasis-color-dark:          $white;
$border-color-dark:                 $gray-700;
$border-color-translucent-dark:     rgba($white, .15);
$headings-color-dark:               inherit;
$link-color-dark:                   tint-color($primary, 40%);
$link-hover-color-dark:             shift-color($link-color-dark, -$link-shade-percentage);
$code-color-dark:                   tint-color($code-color, 40%);
$mark-color-dark:                   $body-color-dark;
$mark-bg-dark:                      $yellow-800;


//
// Forms
//

$form-select-indicator-color-dark:  $body-color-dark;
$form-select-indicator-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color-dark}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>");

$form-switch-color-dark:            rgba($white, .25);
$form-switch-bg-image-dark:         url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color-dark}'/></svg>");

$form-valid-color-dark:             $green-300;
$form-valid-border-color-dark:      $green-300;
$form-invalid-color-dark:           $red-300;
$form-invalid-border-color-dark:    $red-300;


//
// Accordion
//

$accordion-icon-color-dark:         $primary-text-emphasis-dark;
$accordion-icon-active-color-dark:  $primary-text-emphasis-dark;

$accordion-button-icon-dark:         url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>");
$accordion-button-active-icon-dark:  url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>");

Sassミックスイン(Sass mixins)

ダークモード用のスタイルや自分で作成したカスタムカラーモードは、カスタマイズ可能な color-mode() ミックスインを使って data-bs-theme 属性セレクタやメディアクエリに適切に範囲設定できる。詳細は使用方法の項目に記載。

デフォルトの設定
scss/mixins/_color-mode.scss 内 color-mode-mixin の設定@mixin color-mode($mode: light, $root: false) {
  @if $color-mode-type == "media-query" {
    @if $root == true {
      @media (prefers-color-scheme: $mode) {
        :root {
          @content;
        }
      }
    } @else {
      @media (prefers-color-scheme: $mode) {
        @content;
      }
    }
  } @else {
    [data-bs-theme="#{$mode}"] {
      @content;
    }
  }
}