Цветовые режимы
В Bootstrap с версии 5.3.0 появились цветовые режимы (темы). Ознакомьтесь с нашим стандартным светлым режимом и новым темным режимом или создайте свой собственный, используя наши стили как шаблон.
Темный режим
В Bootstrap теперь поддерживаются цветовые режимы, начиная с темного режима! С версии 5.3.0 вы можете реализовать собственный переключатель цветового режима (см. пример ниже из документации Bootstrap) и применять различные цветовые режимы по своему усмотрению. Мы поддерживаем светлый режим (по умолчанию) и теперь темный режим. Цветовые режимы можно переключать глобально на элементе <html>
, либо на отдельных компонентах и элементах с помощью атрибута data-bs-theme
.
В качестве альтернативы вы также можете использовать реализацию на основе медиазапросов благодаря нашему миксину color mode — см. раздел использования для подробностей. Обратите внимание: это убирает возможность менять темы для отдельных компонентов, как показано ниже.
Пример
Например, чтобы изменить цветовой режим выпадающего меню, добавьте data-bs-theme="light"
или data-bs-theme="dark"
к родительскому элементу .dropdown
. Теперь, независимо от глобального цветового режима, эти выпадающие списки будут отображаться с указанным значением темы.
<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="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Другое действие</a></li>
<li><a class="dropdown-item" href="#">Что-то еще</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="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Другое действие</a></li>
<li><a class="dropdown-item" href="#">Что-то еще</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Отдельная ссылка</a></li>
</ul>
</div>
Как это работает
-
Как показано выше, стили цветового режима управляются атрибутом
data-bs-theme
. Этот атрибут можно применить к элементу<html>
или к любому другому элементу или компоненту Bootstrap. Если применить к<html>
, он будет действовать на всё. Если применить к компоненту или элементу — только к нему. -
Для каждого цветового режима, который вы хотите поддерживать, нужно добавить новые переопределения для общих глобальных CSS-переменных. Мы уже делаем это в нашем файле
_root.scss
для темного режима, где светлый режим — это значения по умолчанию. Для написания стилей, специфичных для цветового режима, используйте миксин:// Переменные цветового режима в _root.scss @include color-mode(dark) { // Переопределения CSS-переменных здесь... }
-
Мы используем отдельный файл
_variables-dark.scss
для этих глобальных переопределений CSS-переменных для темного режима. Этот файл не обязателен для ваших собственных цветовых режимов, но он необходим для нашего темного режима по двум причинам. Во-первых, лучше иметь одно место для сброса глобальных цветов. Во-вторых, некоторые переменные Sass пришлось переопределить для фоновых изображений, встроенных в CSS для аккордеонов, форм и других компонентов.
Вложенные цветовые режимы
Используйте data-bs-theme
на вложенном элементе, чтобы изменить цветовой режим для группы элементов или компонентов. В примере ниже у нас внешний темный режим с вложенным светлым. Вы заметите, что компоненты автоматически адаптируют свой внешний вид, но иногда потребуется добавить утилиты, чтобы использовать стили, специфичные для каждого режима.
Например, несмотря на использование data-bs-theme="dark"
на случайном <div>
, у <div>
нет background-color
, так как он задан на <body>
. Поэтому, если вы хотите, чтобы color
и background-color
адаптировались, добавьте классы .text-body
и .bg-body
.
Этот блок всегда должен отображаться в темной теме.
Этот блок всегда должен отображаться в светлой теме.
<div data-bs-theme="dark" class="p-3 text-body bg-body">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Цветовые режимы</a></li>
<li class="breadcrumb-item active" aria-current="page">Темный</li>
</ol>
</nav>
<p>Этот блок всегда должен отображаться в <strong>темной</strong> теме.</p>
<div class="progress mb-4">
<div class="progress-bar" role="progressbar" aria-label="Пример" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="dropdown mb-4">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonDark2" data-bs-toggle="dropdown" aria-expanded="false">
Темное выпадающее меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonDark2">
<li><a class="dropdown-item active" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Другое действие</a></li>
<li><a class="dropdown-item" href="#">Что-то еще</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Отдельная ссылка</a></li>
</ul>
</div>
<div data-bs-theme="light" class="p-3 text-body bg-body rounded">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Цветовые режимы</a></li>
<li class="breadcrumb-item"><a href="#">Темный</a></li>
<li class="breadcrumb-item active" aria-current="page">Светлый</li>
</ol>
</nav>
<p>Этот блок всегда должен отображаться в <strong>светлой</strong> теме.</p>
<div class="progress mb-4">
<div class="progress-bar" role="progressbar" aria-label="Пример" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonLight2" data-bs-toggle="dropdown" aria-expanded="false">
Светлое выпадающее меню
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonLight2">
<li><a class="dropdown-item active" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Действие</a></li>
<li><a class="dropdown-item" href="#">Другое действие</a></li>
<li><a class="dropdown-item" href="#">Что-то еще</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Отдельная ссылка</a></li>
</ul>
</div>
</div>
</div>
Использование
Включение темного режима
Включите встроенный темный цветовой режим для всего проекта, добавив атрибут data-bs-theme="dark"
к элементу <html>
. Это применит темный режим ко всем компонентам и элементам, кроме тех, где явно указан другой data-bs-theme
. На основе шаблона быстрого старта:
<!doctype html>
<html lang="ru" 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.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<h1>Привет, мир!</h1>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</body>
</html>
В Bootstrap пока нет встроенного переключателя цветового режима, но вы можете использовать тот, что есть в нашей документации. Подробнее в разделе JavaScript.
Использование с Sass
Новая опция темного режима доступна всем пользователям Bootstrap, но она управляется через data-атрибуты, а не медиазапросы, и не переключает цветовой режим вашего проекта автоматически. Вы можете полностью отключить темный режим через Sass, изменив $enable-dark-mode
на false
.
Мы используем новый миксин Sass, color-mode()
, чтобы управлять тем, как применяются цветовые режимы. По умолчанию используется подход с data-атрибутом, что позволяет создавать более удобные для пользователя интерфейсы, где посетители могут выбирать автоматический темный режим или управлять предпочтением (как в нашей документации). Это также простой и масштабируемый способ добавить разные темы и собственные цветовые режимы помимо светлого и темного.
Если вы хотите использовать медиазапросы и сделать цветовые режимы только автоматическими, вы можете изменить тип миксина через переменную Sass. Пример и результат компиляции:
$color-mode-type: data;
@include color-mode(dark) {
.element {
color: var(--bs-primary-text);
background-color: var(--bs-primary-bg-subtle);
}
}
Результат:
[data-bs-theme=dark] .element {
color: var(--bs-primary-text);
background-color: var(--bs-primary-bg-subtle);
}
А при установке media-query
:
$color-mode-type: media-query;
@include color-mode(dark) {
.element {
color: var(--bs-primary-text);
background-color: var(--bs-primary-bg-subtle);
}
}
Результат:
@media (prefers-color-scheme: dark) {
.element {
color: var(--bs-primary-text);
background-color: var(--bs-primary-bg-subtle);
}
}
Пользовательские цветовые режимы
Хотя основной сценарий использования цветовых режимов — это светлый и темный режимы, вы также можете создавать собственные цветовые режимы. Создайте свой селектор data-bs-theme
с пользовательским значением в качестве имени цветового режима, затем измените наши переменные Sass и CSS по необходимости. Мы решили создать отдельный файл _variables-dark.scss
для хранения специфичных для темного режима переменных Sass, но для вас это не обязательно.
Например, вы можете создать «синюю тему» с селектором 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, .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
Чтобы дать посетителям или пользователям возможность переключать цветовые режимы, вам нужно создать элемент-переключатель для управления атрибутом data-bs-theme
на корневом элементе <html>
. В нашей документации реализован такой переключатель, который изначально ориентируется на текущий цветовой режим системы пользователя, но позволяет переопределить его и выбрать конкретный режим.
Вот пример JavaScript, который это реализует. Вы можете изучить нашу навигационную панель документации, чтобы увидеть, как это реализовано с помощью HTML и CSS из наших компонентов. Обратите внимание, что если вы решите использовать медиазапросы для цветовых режимов, ваш JavaScript может потребовать изменений или быть удалён, если вы предпочитаете неявное управление.
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
'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)
})
})
})
})()
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)};
--#{$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};
Переменные Sass
CSS-переменные для нашего темного режима частично генерируются из специфичных для темного режима переменных Sass в _variables-dark.scss
. Это также включает некоторые пользовательские переопределения для изменения цветов встроенных SVG, используемых в компонентах.
$primary-text-dark: $blue-300;
$secondary-text-dark: $gray-300;
$success-text-dark: $green-300;
$info-text-dark: $cyan-300;
$warning-text-dark: $yellow-300;
$danger-text-dark: $red-300;
$light-text-dark: $gray-100;
$dark-text-dark: $gray-300;
$primary-bg-subtle-dark: $blue-900;
$secondary-bg-subtle-dark: $gray-900;
$success-bg-subtle-dark: $green-900;
$info-bg-subtle-dark: $cyan-900;
$warning-bg-subtle-dark: $yellow-900;
$danger-bg-subtle-dark: $red-900;
$light-bg-subtle-dark: $gray-800;
$dark-bg-subtle-dark: mix($gray-800, $black);
$primary-border-subtle-dark: $blue-700;
$secondary-border-subtle-dark: $gray-700;
$success-border-subtle-dark: $green-700;
$info-border-subtle-dark: $cyan-800;
$warning-border-subtle-dark: $yellow-800;
$danger-border-subtle-dark: $red-700;
$light-border-subtle-dark: $gray-700;
$dark-border-subtle-dark: $gray-800;
$body-color-dark: $gray-500;
$body-bg-dark: $gray-900;
$body-emphasis-color-dark: $gray-100;
$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%);
$emphasis-color-dark: $white;
$border-color-dark: $gray-700;
$border-color-translucent-dark: rgba($white, .15);
$headings-color-dark: #fff;
$link-color-dark: $blue-300;
$link-hover-color-dark: $blue-200;
$code-color-dark: $pink-300;
//
// 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>");
//
// Accordion
//
$accordion-button-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$primary-text-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='#{$primary-text-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
Стили для темного режима и любых пользовательских цветовых режимов, которые вы создаете, могут быть ограничены селектором атрибута 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;
}
}
}