跳至主要內容 跳至文件導覽
Added in v5.3 View on GitHub

色彩模式(Color modes)

Bootstrap 從 v5.3.0 開始支援色彩模式或主題。探索我們預設的淺色模式和全新的深色模式,或自行建立自訂色彩模式。

親自試試!twbs/examples 儲存庫下載使用 Bootstrap 搭配 Stylelint 和色彩模式的原始碼和工作示範。您也可以在 StackBlitz 中開啟範例

深色模式(Dark mode)

Bootstrap 現在支援色彩模式,從深色模式開始! 使用 v5.3.0,您可以實作自己的色彩模式切換器(請參閱下方來自 Bootstrap 文件的範例)並根據需要套用不同的色彩模式。我們支援淺色模式(預設)和現在的深色模式。色彩模式可以在 <html> 元素上全域切換,或在特定的元件和元素上透過 data-bs-theme 屬性切換。

或者,您也可以透過我們的色彩模式 mixin 切換到媒體查詢實作——詳情請參閱使用方式區段。但請注意,這將消除您按元件切換主題的能力,如下所示。

範例(Example)

例如,要變更下拉選單的色彩模式,請將 data-bs-theme="light"data-bs-theme="dark" 新增至父層 .dropdown。現在,無論全域色彩模式為何,這些下拉選單都會以指定的主題值顯示。

html
<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">
    Default dropdown
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonLight">
    <li><a class="dropdown-item active" href="#">Action</a></li>
    <li><a class="dropdown-item" href="#">Action</a></li>
    <li><a class="dropdown-item" href="#">Another action</a></li>
    <li><a class="dropdown-item" href="#">Something else here</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">Separated link</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">
    Dark dropdown
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonDark">
    <li><a class="dropdown-item active" href="#">Action</a></li>
    <li><a class="dropdown-item" href="#">Action</a></li>
    <li><a class="dropdown-item" href="#">Another action</a></li>
    <li><a class="dropdown-item" href="#">Something else here</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">Separated link</a></li>
  </ul>
</div>

運作原理(How it works)

  • 如上所示,色彩模式樣式由 data-bs-theme 屬性控制。此屬性可以套用至 <html> 元素,或任何其他元素或 Bootstrap 元件。如果套用至 <html> 元素,它將套用至所有內容。如果套用至元件或元素,它將作用於該特定元件或元素。

  • 對於您想要支援的每個色彩模式,您需要為共用的全域 CSS 變數新增覆寫。我們已經在 _root.scss 樣式表中為深色模式這樣做了,淺色模式則是預設值。在撰寫特定色彩模式的樣式時,請使用這個 mixin:

    // Color mode variables in _root.scss
    @include color-mode(dark) {
      // CSS variable overrides here...
    }
    
  • 我們使用自訂的 _variables-dark.scss 來驅動深色模式的共用全域 CSS 變數覆寫。對於您自己的自訂色彩模式,不需要此檔案,但對於我們的深色模式來說,它是必要的,原因有二。首先,最好有一個單一位置來重設全域色彩。其次,某些 Sass 變數必須覆寫,用於嵌入在 CSS 中的手風琴、表單元件等的背景圖片。

使用方式(Usage)

啟用深色模式(Enable dark mode)

透過將 data-bs-theme="dark" 屬性新增至 <html> 元素,在整個專案中啟用內建的深色色彩模式。這將把深色色彩模式套用至所有元件和元素,除了那些已套用特定 data-bs-theme 屬性的。以快速開始範本為基礎:

<!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/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello, world!</h1>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
  </body>
</html>

Bootstrap 尚未內建色彩模式選擇器,但如果您喜歡,可以使用我們文件中的選擇器。在 JavaScript 區段了解更多。

使用 Sass 建構(Building with Sass)

我們的新深色模式選項可供所有 Bootstrap 使用者使用,但它是透過 data 屬性而非媒體查詢控制的,不會自動切換您專案的色彩模式。您可以透過 Sass 將 $enable-dark-mode 變更為 false 來完全停用我們的深色模式。

我們使用自訂的 Sass mixin color-mode() 來幫助您控制_如何_套用色彩模式。預設情況下,我們使用 data 屬性方法,讓您可以建立更友善的使用者體驗,讓訪客可以選擇自動深色模式或控制自己的偏好(就像我們這裡的文件一樣)。這也是一種新增不同主題和更多自訂色彩模式(超越淺色和深色)的簡單且可擴充的方式。

如果您想使用媒體查詢並只讓色彩模式自動化,您可以透過 Sass 變數變更 mixin 的預設類型。請考慮以下程式碼片段及其編譯後的 CSS 輸出。

$color-mode-type: data;

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

輸出為:

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

當設為 media-query 時:

$color-mode-type: media-query;

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

輸出為:

@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 變數。我們選擇建立一個單獨的 _variables-dark.scss 樣式表來存放 Bootstrap 的深色模式特定 Sass 變數,但這對您來說不是必需的。

例如,您可以使用選擇器 data-bs-theme="blue" 建立「藍色主題」。在您的自訂 Sass 或 CSS 檔案中,新增新的選擇器並根據需要覆寫任何全域或元件 CSS 變數。如果您使用 Sass,也可以在 CSS 變數覆寫中使用 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);
  }
}
Example blue theme

Some paragraph text to show how the blue theme might look with written copy.


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

JavaScript

為了讓訪客或使用者能夠切換色彩模式,您需要建立一個切換元素來控制根元素 <html> 上的 data-bs-theme 屬性。我們在文件中建立了一個切換器,它首先遵從使用者目前的系統色彩模式,但提供一個選項來覆寫並選擇特定的色彩模式。

以下是驅動它的 JavaScript。您可以檢視我們自己的文件導覽列,了解如何使用我們自己元件的 HTML 和 CSS 來實作。建議在頁面頂部引入 JavaScript,以減少重新載入網站時可能出現的畫面閃爍。請注意,如果您決定對色彩模式使用媒體查詢,如果您偏好隱式控制,可能需要修改或移除您的 JavaScript。

/*!
 * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
 * Copyright 2011-2025 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)
        })
      })
  })
})()

新增主題色彩(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 無法從現有變數或 map 產生自己的 Sass 變數。在未來版本的 Bootstrap 中,我們將重新審視此設定以減少重複。

// Required
@import "functions";
@import "variables";
@import "variables-dark";

// Add a custom color to $theme-colors
$custom-colors: (
  "custom-color": #712cf9
);
$theme-colors: map-merge($theme-colors, $custom-colors);

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

// Add a custom color to new theme maps

// Light mode
$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);

// Dark mode
$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);

// Remainder of Bootstrap imports
@import "root";
@import "reboot";
// etc

CSS

變數(Variables)

數十個根層級 CSS 變數會作為深色模式的覆寫重複出現。這些變數的作用範圍限定在色彩模式選擇器中,預設為 data-bs-theme,但可以設定為使用 prefers-color-scheme 媒體查詢。使用這些變數作為產生您自己新色彩模式的指南。

--#{$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}highlight-color: #{$mark-color-dark};
--#{$prefix}highlight-bg: #{$mark-bg-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-docs-start theme-text-dark-variables
$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;
// scss-docs-end theme-text-dark-variables

// scss-docs-start theme-bg-subtle-dark-variables
$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);
// scss-docs-end theme-bg-subtle-dark-variables

// scss-docs-start theme-border-subtle-dark-variables
$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;
// scss-docs-end theme-border-subtle-dark-variables

$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>");

// scss-docs-start form-validation-colors-dark
$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;
// scss-docs-end form-validation-colors-dark


//
// 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-.708'/></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-.708'/></svg>");

Sass mixins

深色模式的樣式,以及您建立的任何自訂色彩模式,都可以使用可自訂的 color-mode() mixin 適當地作用於 data-bs-theme 屬性選擇器或媒體查詢。請參閱 Sass 使用方式區段以取得更多詳細資訊。

@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;
    }
  }
}