Перейти к основному контенту Перейти к навигации документации
Добавлено в v5.3 Просмотреть на GitHub

Цветовые режимы

Bootstrap теперь поддерживает цветовые режимы, или темы, начиная с v5.3.0. Изучите наш стандартный светлый цветовой режим и новый темный режим, или создайте свой собственный, используя наши стили в качестве шаблона.

Попробуйте сами! Загрузите исходный код и рабочую демонстрацию для использования Bootstrap с Stylelint и цветовыми режимами из репозитория twbs/examples. Вы также можете открыть пример в StackBlitz.

Темный режим

Bootstrap теперь поддерживает цветовые режимы, начиная с темного режима! С v5.3.0 вы можете реализовать свой собственный переключатель цветовых режимов (см. ниже пример из документации Bootstrap) и применять различные цветовые режимы по своему усмотрению. Мы поддерживаем светлый режим (по умолчанию) и теперь темный режим. Цветовые режимы можно переключать глобально на элементе <html> или на конкретных компонентах и элементах благодаря атрибуту data-bs-theme.

Альтернативно, вы также можете переключиться на реализацию медиа-запросов благодаря нашему миксину цветового режима — см. раздел использования для подробностей. Однако имейте в виду — это исключает вашу возможность изменять темы на основе отдельных компонентов, как показано ниже.

Пример

Например, чтобы изменить цветовой режим выпадающего меню, добавьте 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>

Как это работает

  • Как показано выше, стили цветового режима контролируются атрибутом data-bs-theme. Этот атрибут может быть применен к элементу <html> или к любому другому элементу или компоненту Bootstrap. Если применен к элементу <html>, он будет применяться ко всему. Если применен к компоненту или элементу, он будет ограничен этим конкретным компонентом или элементом.

  • Для каждого цветового режима, который вы хотите поддерживать, вам нужно будет добавить новые переопределения для общих глобальных CSS переменных. Мы уже делаем это в нашей таблице стилей _root.scss для темного режима, при этом светлый режим является значениями по умолчанию. При написании стилей для конкретного цветового режима используйте миксин:

    // Color mode variables in _root.scss
    @include color-mode(dark) {
      // CSS variable overrides here...
    }
    
  • Мы используем пользовательский _variables-dark.scss для питания этих общих переопределений глобальных CSS переменных для темного режима. Этот файл не требуется для ваших собственных пользовательских цветовых режимов, но он необходим для нашего темного режима по двум причинам. Во-первых, лучше иметь одно место для сброса глобальных цветов. Во-вторых, некоторые переменные Sass должны были быть переопределены для фоновых изображений, встроенных в наш CSS для аккордеонов, компонентов форм и многого другого.

Использование

Включение темного режима

Включите встроенный темный цветовой режим во всем вашем проекте, добавив атрибут 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/bootstrap@5.3.8/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/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
  </body>
</html>

Bootstrap пока не поставляется со встроенным переключателем цветовых режимов, но вы можете использовать тот, что из нашей собственной документации, если хотите. Узнайте больше в разделе JavaScript.

Сборка с Sass

Наша новая опция темного режима доступна для использования всеми пользователями Bootstrap, но она контролируется через data-атрибуты вместо медиа-запросов и не переключает автоматически цветовой режим вашего проекта. Вы можете полностью отключить наш темный режим через Sass, изменив $enable-dark-mode на false.

Мы используем пользовательский миксин Sass, color-mode(), чтобы помочь вам контролировать как применяются цветовые режимы. По умолчанию мы используем подход с data-атрибутами, позволяя вам создавать более удобные для пользователя опыты, где ваши посетители могут выбирать автоматический темный режим или контролировать свои предпочтения (как в нашей собственной документации здесь). Это также простой и масштабируемый способ добавления различных тем и дополнительных пользовательских цветовых режимов помимо светлого и темного.

В случае, если вы хотите использовать медиа-запросы и сделать цветовые режимы только автоматическими, вы можете изменить тип миксина по умолчанию через переменную Sass. Рассмотрите следующий фрагмент и его скомпилированный 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);
  }
}

Пользовательские цветовые режимы

Хотя основной случай использования цветовых режимов — это светлый и темный режимы, пользовательские цветовые режимы также возможны. Создайте свой собственный селектор data-bs-theme с пользовательским значением в качестве имени вашего цветового режима, затем измените наши переменные Sass и CSS по мере необходимости. Мы решили создать отдельную таблицу стилей _variables-dark.scss для размещения специфичных для темного режима переменных Sass Bootstrap, но это не требуется для вас.

Например, вы можете создать "синюю тему" с селектором data-bs-theme="blue". В вашем пользовательском файле Sass или CSS добавьте новый селектор и переопределите любые глобальные или компонентные CSS переменные по мере необходимости. Если вы используете Sass, вы также можете использовать функции Sass в ваших переопределениях CSS переменных.

[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, 50%)};
    --bs-btn-border-color: #{rgba($white, .25)};
    --bs-btn-hover-bg: #{darken(mix($gray-600, $blue-400, 50%), 5%)};
    --bs-btn-hover-border-color: #{rgba($white, .25)};
    --bs-btn-active-bg: #{darken(mix($gray-600, $blue-400, 50%), 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

Чтобы позволить посетителям или пользователям переключать цветовые режимы, вам нужно будет создать элемент переключения для контроля атрибута data-bs-theme на корневом элементе <html>. Мы создали переключатель в нашей документации, который изначально отсылает к текущему системному цветовому режиму пользователя, но предоставляет опцию переопределить это и выбрать конкретный цветовой режим.

Вот взгляд на 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)
        })
      })
  })
})()

Добавление цветов темы

Добавления нового цвета в $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 мы пересмотрим эту настройку, чтобы уменьшить дублирование.

// 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

Переменные

Десятки 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 переменные

CSS переменные для нашего темного цветового режима частично генерируются из специфичных для темного режима переменных Sass в _variables-dark.scss. Это также включает некоторые пользовательские переопределения для изменения цветов встроенных 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 миксины

Стили для темного режима и любых пользовательских цветовых режимов, которые вы создаете, могут быть соответствующим образом ограничены селектором атрибута data-bs-theme или медиа-запросом с настраиваемым миксином color-mode(). См. раздел использования 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;
    }
  }
}