В версии Bootstrap 5.3 появилась новая функция — возможность создавать светлую и темную темы для проекта. Теперь не нужно писать кастомные CSS-стили для создания нескольких тем. Всё настраивается через переменные.
В этом уроке мы разберем, как работает светлая и темная темы в Bootstrap. Так же изучим изменение темы и создание собственных.
Переключение светлой и темной тем
В Bootstrap 5.3 светлая и темная темы включены по умолчанию. Для них всё готово. Нужно лишь научится их переключать. Это можно сделать с помощью HTML-атрибута data-bs-theme, который принимает одно из двух значений:
light— светлая тема. Используется по умолчаниюdark— темная тема
Использовать атрибут можно на любом теге HTML, но чаще всего его ставят на весь <body>. Это позволяет задать тему сразу для всего проекта.
В примере можно включать и выключать темную тему, чтобы посмотреть на все изменения.
Если посмотреть на изменения, можно заметить важную особенность — изменяется фон и цвет текста. Основные цвета, такие как 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 в наш первый пример. Теперь при переключении темы меняются и основные цвета проекта.
Выводы
В 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 для светлой темы, во втором для темной. Проверьте, что в каждом контейнере отображаются цвета своей темы.
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.