Что такое Utility API и Utilit-классы в Bootstrap

Utility API - это основанный на Sass инструмент для создания утилит-классов. Utilitу-классы - это небольшие, одноцелевые классы, которые можно использовать для быстрого применения стилей к элементам HTML без необходимости писать пользовательский CSS.

У Бутстрапа есть bootstrap/scss/utilities/api и bootstrap/scss/utilities, которые позволяет создавать свои утилиты(классы высшего порядка) для быстрого прототипирования и адаптивного дизайна. По принципу, похоже на tailwind, но с меньшим количеством классов и более простой системой.

$utilities это масивобоподный объект в SASS, который содержит в себе настройки для генерации утилит-классов. В нем находится список всех утилит(классов), которые будут сгенерированы в итоговом CSS файле и их настройки. Utilities API генерирует классы на основе данных из $utilities.

В _utilities.scss находится масивоподобный объект $utilities с набором свойств и данных для генерации классов утилит.

$utilities: (
...
  "opacity": (
    property: opacity,
    values: (
      0: 0,
      25: .25,
      50: .5,
      75: .75,
      100: 1,
    )
  )
...
);

Cгенерированные утилит-классы имеют высший приоритет, чем базовые классы бутстрапа. Из названий утилит-классов обычно понятно что этот класс делает. К примеру .text-center - центрирует текст, .m-3 - добавляет отступы, .d-flex - делает элемент flex контейнером и т.д.

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

Основные принципы таких утилит-классов:

  1. Атомарные независимые классы
  2. Можно комбинировать между собой
  3. Имеют выше приоритет чем базовые бутстраповские классы

Из минусов: Увеличивается размер итогового css файла, так как генерируется много классов, которые могут не использоваться в проекте. А также кастомизация и рефакторинг может быть сложнее, так как приходится работать с большим количеством классов. К примеру, если нужно изменить цвет текста, то придется найти и заменить все классы .text-*, которые используются в проекте, вместо того что бы поменять это один раз в СSSS файле. А также еще один минус, что простыни классов для каждого элемента могут усложнять HTML разметку.

Свойства для каждой утилиты

OptionTypeDescription
propertyОбязательноИмя свойства, это может быть строка или массив строк (например, горизонтальные паддинги или маргины).
valuesОбязательноСписок значений или карта, если вы не хотите, чтобы имя класса совпадало со значением. Если в качестве ключа карты используется null, он не компилируется.
classНеобязательноПеременная для имени класса, если вы не хотите, чтобы оно совпадало со свойством. Если ключ class не указан, а ключ property — массив строк, имя класса будет первым элементом массива property.
stateНеобязательноСписок вариантов псевдоклассов, таких как :hover или :focus, которые нужно сгенерировать для утилиты. Значение по умолчанию отсутствует.
responsiveНеобязательноБулево значение, указывающее, нужно ли генерировать адаптивные классы. По умолчанию false.
rfsНеобязательноБулево значение для включения fluid rescaling. Подробнее см. на странице RFS. По умолчанию false.
printНеобязательноБулево значение, указывающее, нужно ли генерировать классы для печати. По умолчанию false.
rtlНеобязательноБулево значение, указывающее, должна ли утилита поддерживаться в RTL. По умолчанию true.

N.B. Все утилит-классы, сгенерированные API, включают !important, чтобы гарантировать, что они переопределяют компоненты и классы-модификаторы по назначению. Вы можете переключить эту настройку глобально с помощью переменной $enable-important-utilities (по умолчанию true).

Можно расширять утилиты.

Для этого используем sass функцию map-merge(), которая позволяет объединить два mapа в один.

$utilities: map-merge(
	$utilities,
	(
		"custom-utility": (
			property: custom-property,
			class: custom-class,
			values: (
				key1: value1,
				key2: value2,
			)
		)
	)
);

Важен порядок, сначала нужно объявить $utilities, а потом уже его расширять, и после этого инициализировать utilities/api.

@import "bootstrap/scss/utilities";  
$utilities: map-merge(  
   $utilities,  
   (  
   "height": (  
     property: height,  
     class: h,  
     responsive: true,  
     values: (  
       25: 25%,  
       50: 50%,  
       75: 75%,  
       100: 100%  
     )  
   )  
   )  
);  
@import "bootstrap/scss/utilities/api";

Можно модифицировать существующие утилиты.

Для этого также используем map-merge(), но уже с существующей утилитой, а также map-get() чтобы получить нужные свойства.

К примеру добавить 10% в утилиту width.

@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/utilities";
 
$utilities: map-merge(
  $utilities,
  (
    "width": map-merge(
      map-get($utilities, "width"),
      (
        values: map-merge(
          map-get(map-get($utilities, "width"), "values"),
          (10: 10%),
        ),
      ),
    ),
  )
);

Добавить responsive к существующей утилите-классу.

В Bootstrap 5 все утилиты можно «подстраивать» под брейкпоинты.

{property}{sides?}-{breakpoint?}-{value}

Например: `d-flex, d-sm-flex, d-md-flex, d-lg-flex’

<div class="d-lg-flex">
  Responsive height block
</div>
 

Но Bootstrap 5 не все utilities поддерживают responsive-брейкпоинты «из коробки».

  • Для margin, padding, display, flex, grid, text, color — да, работают -sm-, -md- и т.д.
  • А вот для height/width (h-*, w-*) responsive-версий нет по умолчанию. Поэтому h-md-100 не сработает.

Но есть возможность добавить поддержку responsive к существующим утилитам, например к height и width. Добавив свойство responsive: true в описание утилиты в $utilities.

$utilities: map-merge(  
   $utilities,  
   (  
   "height": (  
     property: height,  
     class: h,  
     responsive: true,  
     values: (  
       25: 25%,  
       50: 50%,  
       75: 75%,  
       100: 100%  
     )  
   )  
   )  
);

Либо еще так более точечно переписать конкретный утилит-класс, к примеру border.

$utilities: map-merge(
  $utilities, (
    "border": map-merge(
      map-get($utilities, "border"),
      ( responsive: true ),
    ),
  )
)
 

Переименование утилит-классов

Это тоже возможно, если не нравится стандартное имя класса. За это отвечает свойство class.

@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/utilities";
 
$utilities: map-merge(
  $utilities, (
    "margin-start": map-merge(
      map-get($utilities, "margin-start"),
      ( class: ml ),
    ),
  )
);

Удалить конкретные утилит-классы из генерации СSS

Удалить любые утилиты по умолчанию, установив ключ группы в null. Например снизу пример как удалить утилиту width.

@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/utilities";
 
$utilities: map-merge(
  $utilities,
  (
    "width": null
  )
);