В версии Bootstrap 5.3 появилась новая функция — возможность создавать светлую и темную темы для проекта. Теперь не нужно писать кастомные CSS-стили для создания нескольких тем. Всё настраивается через переменные.
В этом уроке мы разберем, как работает светлая и темная темы в Bootstrap. Так же изучим изменение темы и создание собственных.
Переключение светлой и темной тем
В Bootstrap 5.3 светлая и темная темы включены по умолчанию. Для них всё готово. Нужно лишь научится их переключать. Это можно сделать с помощью HTML-атрибута data-bs-theme
, который принимает одно из двух значений:
-
light
— светлая тема. Используется по умолчанию -
dark
— темная тема
Использовать атрибут можно на любом теге HTML, но чаще всего его ставят на весь <body>
. Это позволяет задать тему сразу для всего проекта.
В примере ниже можно включать и выключать темную тему, чтобы посмотреть на все изменения:
See the Pen bootstrap_advanced_course_colors_3 by Hexlet (@hexlet) on CodePen.
Если посмотреть на изменения, можно заметить важную особенность — изменяется фон и цвет текста. Основные цвета, такие как primary
и warning
не изменяются, так как это основные цвета темы.
Также не изменяются размеры элементов, их расположение, внутренние и внешние отступы. Всё это не относится к изменениям темы, но можно влиять даже на это с помощью миксина color-mode
.
Иногда возникает необходимость изменить не только фон и цвет текста, но и все основные цвета. Это может происходить по разным причинам, например, текущие цвета слишком яркие или тусклые для темной темы. Переопределим цвета для темной темы сайта.
Изменение темной темы
В уроке про изменение цветовой схемы мы создали новую пастельную схему. Вот как она выглядела:
Ее цвета не такие «агрессивные» для использования на темном фоне. Поэтому сделаем смену основных цветов только для темной темы. Для этого продолжим изменять файл brand-color.scss, который был создан в уроке про цветовые схемы. Вот как он выглядел:
@use "sass:map";
$brand-theme-colors: (
"primary": #a8d8ea,
"secondary": #aa96da,
"success": #bbfcba,
"danger": #fcbad3,
"warning": #ffffd2,
"info": #96a9da,
);
$primary: map.get($brand-theme-colors, "primary");
$secondary: map.get($brand-theme-colors, "secondary");
$success: map.get($brand-theme-colors, "success");
$info: map.get($brand-theme-colors, "info");
$warning: map.get($brand-theme-colors, "warning");
$danger: map.get($brand-theme-colors, "danger");
Чтобы переделать цвета только для темной темы, нужно будет пойти на небольшие хитрости:
-
Создать новые массивы
$theme-colors
и$theme-colors-rgb
-
Сгенерировать новые переменные цветовой схемы
-
Обернуть все переменные и функции в миксин
color-mode
с аргументомdark
-
Изменить порядок подключения файлов в файле main.scss
Пойдем по порядку. Создадим массивы $theme-colors
и $theme-colors-rgb
. Это создаст новую цветовую схему, которую в последствии будем использовать только для элементов с атрибутом data-bs-theme="dark"
:
$brand-theme-colors: (
"primary": #a8d8ea,
"secondary": #aa96da,
"success": #bbfcba,
"danger": #fcbad3,
"warning": #ffffd2,
"info": #96a9da,
);
$primary: map.get($brand-theme-colors, "primary");
$secondary: map.get($brand-theme-colors, "secondary");
$success: map.get($brand-theme-colors, "success");
$info: map.get($brand-theme-colors, "info");
$warning: map.get($brand-theme-colors, "warning");
$danger: map.get($brand-theme-colors, "danger");
$theme-colors: (
"primary": $primary,
"secondary": $secondary,
"success": $success,
"danger": $danger,
"warning": $warning,
"info": $info,
);
// С помощью функции to-rgb()
// переводим цвета в формат RGB
$theme-colors-rgb: (
"primary": to-rgb($primary),
"secondary": to-rgb($secondary),
"success": to-rgb($success),
"danger": to-rgb($danger),
"warning": to-rgb($warning),
"info": to-rgb($info),
);
Важно, что мы создаем массив $theme-colors-rgb
, где все цвета переводятся в модель rgb
. В таком формате используются цвета в некоторых компонентах. Например, в формате RGB используются цвета в тексте:
.text-info {
--bs-text-opacity: 1;
color: rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important;
}
/* --bs-info-rgb: 13,202,240; */
Теперь используем новые массивы и сгенерируем цвета. Для этого используем два цикла, которые сгенерируют переменные:
// Генерация переменных из массива $theme-colors
@each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{$value};
}
// Генерация переменных из массива $theme-colors-rgb
@each $color, $value in $theme-colors-rgb {
--#{$prefix}#{$color}-rgb: #{$value};
}
Этот код сгенерирует 12 переменных:
--bs-primary: #a8d8ea;
--bs-secondary: #aa96da;
--bs-success: #bbfcba;
--bs-danger: #fcbad3;
--bs-warning: #ffffd2;
--bs-info: #96a9da;
--bs-primary-rgb: 168, 216, 234;
--bs-secondary-rgb: 170, 150, 218;
--bs-success-rgb: 187, 252, 186;
--bs-danger-rgb: 252, 186, 211;
--bs-warning-rgb: 255, 255, 210;
--bs-info-rgb: 150, 169, 218;
Чтобы эти переменные использовались только на темной теме, весь написанный код нужно обернуть в миксин color-mode
со значением dark
. Это добавит переменные в CSS-селектор [data-bs-theme=dark]
:
@use "sass:map";
@include color-mode(dark) {
$brand-theme-colors: (
"primary": #a8d8ea,
"secondary": #aa96da,
"success": #bbfcba,
"danger": #fcbad3,
"warning": #ffffd2,
"info": #96a9da,
);
$primary: map.get($brand-theme-colors, "primary");
$secondary: map.get($brand-theme-colors, "secondary");
$success: map.get($brand-theme-colors, "success");
$info: map.get($brand-theme-colors, "info");
$warning: map.get($brand-theme-colors, "warning");
$danger: map.get($brand-theme-colors, "danger");
$theme-colors: (
"primary": $primary,
"secondary": $secondary,
"success": $success,
"danger": $danger,
"warning": $warning,
"info": $info,
);
$theme-colors-rgb: (
"primary": to-rgb($primary),
"secondary": to-rgb($secondary),
"success": to-rgb($success),
"danger": to-rgb($danger),
"warning": to-rgb($warning),
"info": to-rgb($info),
);
@each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{$value};
}
@each $color, $value in $theme-colors-rgb {
--#{$prefix}#{$color}-rgb: #{$value};
}
}
Осталось подключить файл с цветовой схемой. Тут есть хитрость — подключить файл уже после подключения фреймворка. В Bootstrap еще не отточена система с изменением темной цветовой схемы, так как нет отдельного массива $theme-colors
в настройках проекта.
По этой причине вначале полностью подключается Bootstrap, а затем отдельно подключается новая темная цветовая схема.
@import "../../node_modules/bootstrap/scss/bootstrap.scss";
@import "./brand-color";
После компиляции в CSS-файле появится следующий код:
[data-bs-theme=dark] {
--bs-primary: #a8d8ea;
--bs-secondary: #aa96da;
--bs-success: #bbfcba;
--bs-danger: #fcbad3;
--bs-warning: #ffffd2;
--bs-info: #96a9da;
--bs-primary-rgb: 168, 216, 234;
--bs-secondary-rgb: 170, 150, 218;
--bs-success-rgb: 187, 252, 186;
--bs-danger-rgb: 252, 186, 211;
--bs-warning-rgb: 255, 255, 210;
--bs-info-rgb: 150, 169, 218;
}
Добавим этот CSS в наш первый пример. Теперь при переключении темы меняются и основные цвета проекта:
See the Pen bootstrap_advanced_course_dark-theme_1 by Hexlet (@hexlet) on CodePen.
Выводы
В Bootstrap 5.3 появилась возможность использовать несколько цветовых схем. Главным мотиватором такого решения стала возможность добавлять светлую и темную тему для проекта.
Переключение тем происходит с помощью изменения атрибута data-bs-theme
. Этот атрибут может использоваться как на отдельном компоненте, так и на всем проекте. Для всего проекта атрибут устанавливают для тега <html>
или <body>
. Чтобы установить темную тему, используется значение dark
.
Чтобы добавить произвольные цвета в цветовую схему для темной темы, используется следующий алгоритм:
-
Создаются новые массивы $theme-colors и $theme-colors-rgb
-
С помощью циклов генерируются CSS-переменные из созданных массивов
-
Весь код оборачивается в миксин
color-mode
с аргументомdark
. Это позволит сгенерировать переменные только для селектора[data-bs-theme=dark]
-
В основном файле проекта новые цвета подключаются уже после подключения всего фреймворка
Самостоятельная работа
Повторите шаги по созданию нескольких цветовых тем из урока. Добавьте цвета для светлой и темной темы. В шаблоне со страницей создайте два контейнера с элементами, использующими цвета темы. В первом контейнере укажите значение в атрибуте data-bs-theme
для светлой темы, во втором для темной. Проверьте, что в каждом контейнере отображаются цвета своей темы.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.