Зарегистрируйтесь, чтобы продолжить обучение

Создание пользовательских утилит Bootstrap 5: Продвинутый уровень

При использовании Bootstrap разработчики часто используют утилиты — небольшие классы, которые добавляют новые CSS-свойства к компоненту. Например, утилита d-* устанавливает один из видов отображения с помощью свойства display:

  • block

  • flex

  • inline

  • none

  • table

Внутри фреймворка уже определены десятки утилит, которых хватит «на все случаи жизни». Но при разработке большого проекта может возникнуть потребность в создании новой утилиты или дополнения уже существующей.

Для этого в Bootstrap 5 используется Utility API — набор SASS функций, которые преобразуют массив свойств в утилиты.

В этом уроке рассмотрим создание новой утилиты cursor и изменим утилиту background. Мы научимся добавлять возможность менять цвет фона блока при наведении на него курсора мыши.

Utility API

Рассмотрим, как выглядит утилита в Bootstrap с точки зрения Utility API. Для этого достаточно открыть файл по пути bootstrap/scss/_utilities.scss и выбрать любую утилиту из массива. Для примера возьмем утилиту width:

"width": (
  property: width,
  class: w,
  values: (
    25: 25%,
    50: 50%,
    75: 75%,
    100: 100%,
    auto: auto
  )
)

Здесь представлена базовая структура любой утилиты:

  • property — CSS-свойство, которое будет изменяться

  • class — имя класса утилиты. Для ширины утилита будет иметь классы w-*

  • values — список CSS-значений. Это массив, где ключ — название, которое будет использовано в названии класса, а значение — содержание свойства

После компиляции появятся классы:

.w-25 {
  width: 25% !important;
}

.w-50 {
  width: 50% !important;
}

.w-75 {
  width: 75% !important;
}

.w-100 {
  width: 100% !important;
}

.w-auto {
  width: auto !important;
}

Поля property и values — обязательные. Без них Bootstrap не скомпилируется и выдаст ошибку.

class является необязательным полем. Если его не указать, то в качестве названия утилиты, будет взято значение из поля property.

Старайтесь создавать утилиты с понятными именами. Конечное название класса должно быть понятным для разработчиков. Например, сокращать свойство background до b не лучший вариант, так как такое название неоднозначно.

Настало время создать новую утилиту.

Создание утилиты Cursor

Перед созданием утилиты определим, какое свойство изменяется и какое значение необходимо получить.

В этой утилите мы будем добавлять для блока свойство cursor, которое изменяет внешний вид курсора. Свойство принимает множество значений, но выберем основные:

  • pointer

  • help

  • wait

  • progress

  • zoom-in

  • zoom-out

  • none

Как и с компонентами, мы не будем изменять внутренние файлы Bootstrap, а создадим отдельный файл для утилит:

bootstrap-project/
├── app/
│   ├── scss/
│   │   ├── main.scss
│   │   └── utilities/
│   │       └── utilities.scss
|   └── index.pug
├── build/
├── node_modules/
├── package-lock.json
├── package.json
└── gulpfile.js

В файл добавим новую утилиту. Для этого смержим уже существующий массив с утилитами $utilities и новым массивом утилиты cursor:

@use 'sass:map';

$utilities: map.merge(
  $utilities,
  (
    "cursor": (
      property: cursor,
      values: pointer help wait progress zoom-in zoom-out none,
    )
  )
);

В массиве values не используется схема «ключ-значение». Значит, в имени класса будет использоваться полное название значения свойства. Например, .cursor-pointer.

Схема подключения файла с генерацией утилит отличается от подключения файла с компонентами. Хитрость в том, что нужно подключить утилиты не до или после подключения Bootstrap, а между подключением файла утилит и генерацией самих классов.

Для этого используется такая структура подключения файлов:

// Подключаем базовые функции, переменные и миксины
@import "../../node_modules/bootstrap/scss/functions";
@import "../../node_modules/bootstrap/scss/variables";
@import "../../node_modules/bootstrap/scss/variables-dark";
@import "../../node_modules/bootstrap/scss/maps";
@import "../../node_modules/bootstrap/scss/mixins";
@import "../../node_modules/bootstrap/scss/utilities";

// Подключаем файл с нашими утилитами
@import "./utilities/utilities";

// Подключаем генерацию утилит
@import "../../node_modules/bootstrap/scss/utilities/api";

// Подключаем весь Bootstrap
@import "../../node_modules/bootstrap/scss/bootstrap.scss";

Сгенерируем весь проект и получим новые классы утилит:

.cursor-pointer {
  cursor: pointer !important;
}

.cursor-help {
  cursor: help !important;
}

.cursor-wait {
  cursor: wait !important;
}

.cursor-progress {
  cursor: progress !important;
}

.cursor-zoom-in {
  cursor: zoom-in !important;
}

.cursor-zoom-out {
  cursor: zoom-out !important;
}

.cursor-none {
  cursor: none !important;
}

Теперь эти утилиты можно использовать в своем проекте и изменять их при необходимости. Например, использовать изменение курсора при наведении мыши на элемент.

Рассмотрим изменение утилиты на примере свойства background.

Изменение утилиты

Изменение утилиты не сильно отличается от создания новой. Нужно скопировать все значения старой утилиты и добавить в нее новое свойство.

Для примера изменим утилиту background и добавим возможность изменять цвет блока при наведении. За создание утилит, которые работают при псевдоклассе (:hover, :focus и т.д.) отвечает свойство Utility API state. Если добавить в него название псевдокласса, сгенерируются новые классы:

@use 'sass:map';

$utilities: map.merge(
  $utilities,
  (
    "background-color": map.merge(
      map.get($utilities, "background-color"),
      (
        state: hover
      ),
    ),
  )
);

После компиляции проекта помимо классов bg-primary bg-seccondary появятся новые классы, которые работают при наведении на элемент:

.bg-primary-hover:hover {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;
}

.bg-secondary-hover:hover {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;
}

.bg-success-hover:hover {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;
}

.bg-info-hover:hover {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;
}

/* и так далее для всех цветов в проекте */

Все возможные свойства Utility API указаны в документации. Не бойтесь экспериментировать и создавать новые утилиты.

Выводы

В этом уроке мы познакомились с возможностью Bootstrap под названием Utility API. Это АПИ позволяет генерировать новые и изменять уже существующие утилиты без ручного написания классов.

Utility API позволяет существенно расширять возможность утилит и добавлять им:

  • Работу для разных разрешений экрана

  • Работу для разных состояний элемента

  • Дополнять или удалять значения

Это поможет составить грамотную дизайн-систему, которая легко расширяется и обновляется вместе с обновлением самого Bootstrap.


Самостоятельная работа

Повторите шаги из урока создав утилиту Cursor. Добавьте утилиту в файл utilities.scss. Подключите утилиту в main.scss и все необходимые элементы. Добавьте шаблон страницы элементы, которые используют утилиту. Проверьте, что курсор меняется при наведении на элементы.


Дополнительные материалы

  1. Utility API

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу