# Дизайн-система Bootstrap

## Предварительный просмотр интерфейса дизайн-системы Bootstrap

Фильтруйте бронирования, проверяйте поля, просматривайте данные в нативном модальном окне и переключайтесь между светлой и тёмной темами.

## Справочник по дизайну системы дизайн-система Bootstrap

Скомпилированные значения Bootstrap 5.3.8 по умолчанию CSS и документация версии 5.3. Значения приведены по умолчанию и не являются обязательными правилами бренда. Сравнение rem с пикселями предполагает корневой размер шрифта 16px; на меньших экранах адаптивные размеры шрифта могут отличаться от значений для больших экранов. У окружающей страницы OpenDesign остаётся собственная типографика.

### Семантические цвета и роли поверхностей

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| --bs-primary | #0d6efd | Базовый цвет основных действий и ссылок. |
| --bs-secondary | #6c757d | Дополнительное семейство цветов темы; это не адаптивная роль вторичного цвета основного текста. |
| --bs-success | #198754 | Базовый цвет позитивного статуса; дополните его текстовой меткой. |
| --bs-danger | #dc3545 | Базовый цвет темы ошибки или деструктивного действия. |
| --bs-warning | #ffc107 | Базовый цвет темы предупреждения; проверьте контрастность текста. |
| --bs-info | #0dcaf0 | Базовый цвет информационной темы. |
| --bs-body-bg | #fff | Поверхность страницы в светлой теме. |
| --bs-body-color | #212529 | Цвет основного текста в светлой теме. |
| --bs-secondary-bg | #e9ecef | Вторичная поверхность в светлой теме. |
| --bs-tertiary-bg | #f8f9fa | Ненавязчивая поверхность панели в светлой теме. |
| --bs-primary-bg-subtle | #cfe2ff | Тонированная поверхность основного цвета в светлой теме. |
| --bs-primary-text-emphasis | #052c65 | Текст для поверхностей с лёгким оттенком основного цвета. |
| --bs-border-color | #dee2e6 | Роль границы в светлой теме. |
### Типографика основного текста и удобная для чтения иерархия

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| --bs-body-font-size | 1rem | Размер основного текста по умолчанию: 1rem, обычно 16px. |
| --bs-body-line-height | 1.5 | Множитель без единиц измерения: обычно высота строки составляет 24px. |
| --bs-body-font-weight | 400 | Обычная насыщенность основного текста. |
| --bs-body-font-family | var(--bs-font-sans-serif) | Системный стек интерфейса, предоставляемый Bootstrap. |
| --bs-font-monospace | SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace | Для кода и технических значений используется моноширинный стек. |
### Размеры заголовков и утилиты для крупного текста

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| h1 / .h1 | 2.5rem | Размер для больших экранов; для h1–h4 по умолчанию используется адаптивный размер шрифта. |
| h2 / .h2 | 2rem | Размер для больших экранов; для h1–h4 по умолчанию используется адаптивный размер шрифта. |
| h3 / .h3 | 1.75rem | Размер для больших экранов; для h1–h4 по умолчанию используется адаптивный размер шрифта. |
| h4 / .h4 | 1.5rem | Размер для больших экранов; для h1–h4 по умолчанию используется адаптивный размер шрифта. |
| h5 / .h5 | 1.25rem | Фиксированный размер заголовка по умолчанию. |
| h6 / .h6 | 1rem | Фиксированный размер заголовка по умолчанию. |
| .lead | 1.25rem / weight 300 | Вводный текст; не заменяет заголовок. |
| .small | 0.875em | Относительно мелкий текст; используйте выборочно для метаданных. |
### Шкала утилит отступов

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| 0 | 0 | Используйте с утилитами m/p/gap/g; например, p-0. |
| 1 | 0.25rem | Используйте с утилитами m/p/gap/g; например, p-1. |
| 2 | 0.5rem | Используйте с утилитами m/p/gap/g; например, p-2. |
| 3 | 1rem | Используйте с утилитами m/p/gap/g; например, p-3. |
| 4 | 1.5rem | Используйте с утилитами m/p/gap/g; например, p-4. |
| 5 | 3rem | Используйте с утилитами m/p/gap/g; например, p-5. |
| ms / me | inline start / end | Логическое обозначение сторон; в отличие от ml/mr в более старых версиях Bootstrap. |
| p-3 p-md-4 | 1rem → 1.5rem at md | Адаптивный внутренний отступ, используемый в примере. |
| gap-2 | 0.5rem | Расстояние между дочерними элементами flex/grid. |
### Адаптивные пороги сетки

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| xs / .col- | 0 | Базовый уровень, без префикса xs. |
| sm / .col-sm- | 576px | Малый уровень; максимальная ширина .container — 540px. |
| md / .col-md- | 768px | Средний уровень; максимальная ширина .container — 720px. |
| lg / .col-lg- | 992px | Большой уровень; максимальная ширина .container — 960px. |
| xl / .col-xl- | 1200px | Очень большой уровень; максимальная ширина .container — 1140px. |
| xxl / .col-xxl- | 1400px | Самый большой уровень по умолчанию; максимальная ширина .container — 1320px. |
| Grid columns | 12 | Сочетание col-lg-7 и col-lg-5 заполняет одну строку. |
| Default horizontal gutter | 1.5rem | Внутренний отступ столбца — 0.75rem с каждой стороны; строка компенсирует его отрицательными внешними отступами. |
### Скругление границ и высота тени

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| --bs-border-width | 1px | Толщина границы по умолчанию. |
| --bs-border-radius | 0.375rem | Поля, карточки и скругление углов по умолчанию. |
| --bs-border-radius-sm | 0.25rem | Компактное скругление. |
| --bs-border-radius-lg | 0.5rem | Более выраженное скругление. |
| --bs-border-radius-xl | 1rem | Сильное скругление поверхности. |
| --bs-border-radius-xxl | 2rem | Очень сильное скругление поверхности. |
| --bs-border-radius-pill | 50rem | Форма капсулы, а не измеренный радиус компонента. |
| --bs-box-shadow-sm | 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) | Ненавязчивая тень. |
| --bs-box-shadow | 0 0.5rem 1rem rgba(0, 0, 0, 0.15) | Высота по умолчанию. |
| --bs-box-shadow-lg | 0 1rem 3rem rgba(0, 0, 0, 0.175) | Выраженная тень; не применяйте её ко всем поверхностям. |
### Размеры кнопок и переменные состояний

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| --bs-btn-padding-x | 0.75rem | Горизонтальный внутренний отступ кнопки по умолчанию. |
| --bs-btn-padding-y | 0.375rem | Вертикальный внутренний отступ кнопки по умолчанию. |
| --bs-btn-font-size | 1rem | Размер текста кнопки по умолчанию. |
| --bs-btn-line-height | 1.5 | Множитель высоты строки текста кнопки по умолчанию. |
| --bs-btn-border-width | 1px | Толщина границы по умолчанию. |
| --bs-btn-border-radius | var(--bs-border-radius) | Радиус скругления кнопки по умолчанию. |
| --bs-btn-disabled-opacity | 0.65 | Визуальное оформление; также используйте настоящий атрибут disabled. |
### Изменение ролей в светлой и тёмной темах

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| --bs-body-bg | light #fff / dark #212529 | Фон страницы зависит от data-bs-theme. |
| --bs-body-color | light #212529 / dark #dee2e6 | Цвет текста адаптируется к поверхности. |
| --bs-border-color | light #dee2e6 / dark #495057 | Граница, адаптирующаяся к теме. |
| --bs-primary-bg-subtle | light #cfe2ff / dark #031633 | Фон с оттенком статуса меняется в зависимости от темы. |
| --bs-primary-text-emphasis | light #052c65 / dark #6ea8fe | Используйте вместе с соответствующей поверхностью с лёгким оттенком. |
| data-bs-theme | light \| dark | Задайте на уровне всего html или локальной вложенной области. |
## Полное руководство по дизайн-системе Bootstrap

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

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

## Дизайн-система Bootstrap: выберите CSS и обязанности JavaScript для Bootstrap

### Одна таблица стилей, поведение компонентов — по желанию

> Скомпилированная таблица стилей Bootstrap предоставляет сетку, типографику, утилиты и оформление компонентов. Пакет JavaScript добавляет интерактивные плагины, например Modal, Collapse и Dropdown. Для стилизованной кнопки JavaScript не нужен, а для запуска модального окна через data-bs-toggle — нужен. В рабочем предварительном просмотре локально загружаются соответствующие таблица стилей и пакет версии 5.3.8, чтобы элементы управления демонстрировали реальные принципы их работы.

Фильтрация таблицы бронирований, сводка ошибок и локальное добавление строк реализованы в коде приложения. Такое разделение позволяет заменить вымышленные записи данными сервиса, не приписывая логику бронирования самому Bootstrap.

- CSS: макет, типографика, кнопки, поля, таблицы и оформление состояний.

- Bootstrap JavaScript: открытие модального окна, фон-затемнение, реакция на Escape и управление фокусом.

- JavaScript приложения: сообщения проверки, фильтрация записей и локальное обновление данных.

Прочитать вспомогательную спецификацию

### Выберите скомпилированный CSS или сборку Sass

Выберите скомпилированный CSS для быстрого старта или продукта, в котором можно использовать стандартный набор утилит. Исходный код Sass подойдёт, если нужно изменить карты темы, генерацию утилит или сетку на этапе сборки. Пользовательские свойства CSS во время выполнения подходят для настройки отдельных компонентов, но изменение корневой цветовой переменной не пересобирает все заранее скомпилированные варианты.

```
$primary: #3159a5;
$border-radius: .5rem;
@import "bootstrap/scss/bootstrap";
```

Справочник по коду

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: семантические цвета и цветовые режимы

### Сочетайте поверхность статуса с соответствующим цветом текста

Для значков бронирования используются bg-primary-subtle и text-primary-emphasis. Это парные семантические роли: цвет текста и фон адаптируются при изменении data-bs-theme. Однотонный синий фон в сочетании с произвольным серым текстом лишает их этой связи. Кроме того, статусы «Забронировано», «Используется» и «Черновик» по-прежнему обозначены текстом: цвет — не единственный способ передать их смысл.

```
<span class="badge text-primary-emphasis bg-primary-subtle">Reserved</span>
<section data-bs-theme="dark">
  <div class="bg-body text-body border rounded p-3">Theme-scoped content</div>
</section>
```

Справочник по коду

Прочитать вспомогательную спецификацию

### Ограничивайте настройку рамками компонента

Для отдельного пользовательского действия переопределите локальные свойства --bs-btn-*. Задайте значения не только для обычного фона, но и для состояний hover и active. Пример ниже показывает вариант для приложения, а не значение по умолчанию в Bootstrap. Применяйте этот класс только к нужной кнопке, чтобы он случайно не повлиял на все основные действия в другой части страницы.

```
.btn-reserve {
  --bs-btn-color: #fff;
  --bs-btn-bg: #3159a5;
  --bs-btn-border-color: #3159a5;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #274783;
  --bs-btn-hover-border-color: #274783;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #203a6b;
  --bs-btn-active-border-color: #203a6b;
}
```

Справочник по коду

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: используйте фактическую шкалу типографики

### Разделяйте семантику документа и визуальный размер

Главный заголовок предварительного просмотра — элемент h1 с классом h3: он остаётся основным заголовком страницы, но использует меньший визуальный размер, подходящий для инструмента. Заголовки разделов — элементы h2 со стилем h5. Bootstrap предоставляет стили как для самих элементов, так и для соответствующих классов заголовков, позволяя разделить семантику и оформление без пропуска уровней в структуре документа.

Размер основного текста по умолчанию — 1rem, высота строки — 1.5. Размеры от h1 до h4 адаптивно увеличиваются и достигают значений из справочной таблицы. Поэтому снимок экрана при одной ширине не отражает всю шкалу типографики. Используйте скомпилированные стили или описанное поведение Sass, а не копируйте размер в пикселях, измеренный в одном окне просмотра.

Прочитать вспомогательную спецификацию

### Назначьте вторичному тексту роль, адаптирующуюся к теме

text-body-secondary зависит от цветового режима основного текста. Этот стиль подходит для дополнительной информации о записи, например имени владельца под названием оборудования. Класс small уменьшает текст относительно окружающего, поэтому его не следует применять ко всем подписям полей: форму станет сложнее быстро просматривать. Оставляйте подписи в стандартном размере формы, а компактный текст используйте для подсказок и метаданных.

```
<h1 class="h3">Equipment reservations</h1>
<p class="text-body-secondary">Review availability before booking.</p>
<small class="text-body-secondary">Local demonstration data</small>
```

Справочник по коду

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: создавайте макеты с помощью утилит отступов и сетки

### Используйте шкалу вместо произвольных интервалов

p-3 задаёт внутренний отступ 1rem, p-4 — 1.5rem, а p-5 увеличивает его до 3rem. Обозначения — это ключи шкалы, а не значения в пикселях. В примере используется p-3 p-md-4: при ширине 768px внешний внутренний отступ увеличивается, а mb-3 разделяет группы полей интервалом 1rem. Это правило относится к данному примеру и не создаёт новую официальную шкалу отступов.

```
<div class="p-3 p-md-4">
  <div class="d-flex flex-wrap gap-2 mb-3">
    <button class="btn btn-primary">Review</button>
    <button class="btn btn-outline-secondary">Reset</button>
  </div>
</div>
```

Справочник по коду

Прочитать вспомогательную спецификацию

### Сохраняйте связь между строками и столбцами

В примере используется row g-4 с col-lg-7 и col-lg-5. До пороговой ширины lg в 992px обе секции занимают всю ширину, а затем делят строку из двенадцати столбцов. Размещайте столбцы сетки внутри строки: её отрицательный внешний отступ компенсирует внутренние отступы столбцов. Дополнительный произвольный отступ вокруг каждого столбца может нарушить это выравнивание.

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: создавайте поля с явными связями

### Свяжите подписи, подсказки и сообщения об ошибках

form-label оформляет настоящую метку; её значение for должно совпадать с id поля ввода. form-control оформляет текстовые поля ввода, а form-select — список выбора. В примере aria-describedby связывает поле с подсказкой и сообщением об ошибке, а required задаёт реальное ограничение. Имена классов сами по себе не создают эти семантические связи.

```
<label for="equipment" class="form-label">Equipment</label>
<select id="equipment" class="form-select" required
  aria-describedby="equipment-error">
  <option value="">Choose equipment</option>
  <option>Camera kit A</option>
</select>
<div class="invalid-feedback" id="equipment-error">Choose equipment.</div>
```

Справочник по коду

Прочитать вспомогательную спецификацию

### Используйте настоящее состояние ошибки и доступную сводку

При отправке примера проверяется каждое поле, задаются is-invalid и aria-invalid, создаются текстовые ссылки на поля с ошибками, а фокус переводится на сводку. Исправление поля обновляет его состояние, не удаляя другие ответы. Этот прикладной слой необходим: в документации Bootstrap предупреждается, что одни лишь пользовательские визуальные подсказки не полностью доступны вспомогательным технологиям.

1. Перед тем как отметить поле как ошибочное, проверьте результат фактической проверки ограничений.

2. Свяжите текст ошибки с полем и сообщите о его недопустимом состоянии.

3. После отправки переместите фокус на полезную сводку или первое поле с ошибкой.

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: показывайте записи и фильтруйте их, сохраняя смысл

### Используйте компонент таблицы для сопоставимых данных

В таблице есть заголовки столбцов и строк, а также подпись. table-hover добавляет подсветку при наведении, но не превращает строки в кнопки. Фильтрация скрывает подходящие строки и обновляет число результатов в области aria-live. Статус показан текстом внутри бейджа, поэтому его смысл сохраняется при смене цветового режима.

```
<div class="table-responsive">
  <table class="table table-hover">
    <caption>Fictional equipment reservations</caption>
    <thead><tr><th scope="col">Equipment</th><th scope="col">Status</th></tr></thead>
    <tbody><tr><th scope="row">Camera kit A</th><td>Reserved</td></tr></tbody>
  </table>
</div>
```

Справочник по коду

Прочитать вспомогательную спецификацию

### Ограничьте прокрутку таблицы областью данных

table-responsive добавляет горизонтальную прокрутку, если широкая таблица не помещается. Не размещайте внутри этой обёртки выпадающий список, которому нужно выходить за её границы, не проверив его поведение. В примере фильтр находится над таблицей. На мобильных устройствах горизонтально прокручиваться может только область данных; сама страница должна помещаться в окне просмотра.

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: проверьте выбор в модальном окне API

### Открывайте окно, только если форма прошла проверку

Интерактивный пример создаёт экземпляр Bootstrap Modal или использует уже существующий и вызывает show только после успешной проверки. Так слой проверки не перекрывает ошибки, требующие внимания. Текст заполняется текущими значениями; при выборе «Изменить данные» модальное окно закрывается, а данные формы сохраняются.

```
const element = document.getElementById("review-modal");
const modal = bootstrap.Modal.getOrCreateInstance(element);
// Run after validation and after populating the review text.
modal.show();
element.addEventListener("hidden.bs.modal", () => {
  document.querySelector("#reservation button[type=submit]").focus();
});
```

Справочник по коду

Прочитать вспомогательную спецификацию

### Учитывайте жизненный цикл компонента модального окна

Bootstrap управляет фоном и переходом. Используйте его методы и события, а не переключайте display вручную: иначе фокус или фон могут работать некорректно. При подтверждении в этой демонстрации добавляется строка в локальную таблицу и закрывается модальное окно; запрос к сервису бронирования не отправляется. Сообщение об успехе точно описывает этот локальный результат.

Прочитать вспомогательную спецификацию

## Дизайн-система Bootstrap: интегрируйте и расширяйте этот пример Bootstrap

### Подключите соответствующие версии CSS и JavaScript

Встроенный пример использует локально сохранённые файлы Bootstrap 5.3.8 CSS и bundle. Атрибуты данных и API Modal взяты из этого релиза. В приложении Vite импортируйте скомпилированный CSS и необходимый плагин, как показано в разделе настройки. Не подключайте bundle и не запускайте вторую копию того же плагина через другую обёртку.

Прочитать вспомогательную спецификацию

### Расширяйте пример в соответствии с контрактом компонента

Чтобы добавить поле формы, задайте для него метку, id, ограничение, связанное сообщение и обработку проверки. Чтобы добавить состояние записи, определите его текст и подходящую пару семантических бейджей. Чтобы изменить компоновку, выберите контрольную точку и разделение сетки из приведённого выше справочника. Это конкретные расширения работающего примера, а не предложение придумать новый язык интерфейса.

- Используйте пример, чтобы проверить фокус, закрытие модального окна и смену темы.

- Отделяйте операции с данными приложения от поведения плагина Bootstrap.

- Проверяйте каждое переопределение темы в обычном состоянии, при наведении, фокусе, ошибке и отключении.

Прочитать вспомогательную спецификацию

## Примеры компонентов дизайн-системы Bootstrap

### index.html — полный пример бронирования

Полная страница Bootstrap 5.3.8 со стилями, средой выполнения модального окна, проверкой, фильтрами и локальным подтверждением. Сохраните этот файл как index.html и запустите сервер в папке командой ниже. Для закреплённых зависимостей CDN требуется подключение к сети.

```
<!doctype html><html lang="en" data-bs-theme="light"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Bootstrap equipment reservations — OpenDesign example</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"><style>body{margin:0}main{max-width:1120px;margin:auto}.demo-stat{font-variant-numeric:tabular-nums}.table td,.table th{vertical-align:middle}.table caption{font-size:.875rem}.demo-status:empty{display:none}@media(max-width:575px){.table th,.table td{font-size:.8125rem;padding:.65rem .4rem}.demo-mobile-hide{display:none}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}}</style></head><body>
<header class="border-bottom bg-body-tertiary px-3 px-md-4 py-3 d-flex align-items-center justify-content-between gap-3"><div><strong>Studio inventory</strong><span class="badge text-bg-primary ms-2">Bootstrap 5.3.8</span></div><button id="theme" type="button" class="btn btn-outline-secondary btn-sm" aria-pressed="false">Dark mode</button></header>
<main class="p-3 p-md-4"><div class="d-flex align-items-start justify-content-between gap-3 mb-4"><div><p class="text-body-secondary small mb-1">EQUIPMENT / RESERVATIONS</p><h1 class="h3 mb-2">Keep the next shoot ready.</h1><p class="text-body-secondary mb-0">Check equipment, create a local reservation and review its details.</p></div><span class="badge rounded-pill text-primary-emphasis bg-primary-subtle border border-primary-subtle demo-mobile-hide">Interactive example</span></div>
<div class="row g-3 mb-4"><div class="col-4"><div class="border rounded p-3"><div class="text-body-secondary small">Equipment</div><strong class="fs-3 demo-stat">12</strong></div></div><div class="col-4"><div class="border rounded p-3"><div class="text-body-secondary small">Reservations</div><strong id="count" class="fs-3 demo-stat">3</strong></div></div><div class="col-4"><div class="border rounded p-3"><div class="text-body-secondary small">Available</div><strong class="fs-3 demo-stat">8</strong></div></div></div>
<div class="row g-4"><section class="col-lg-7" aria-labelledby="list-title"><div class="d-flex align-items-center justify-content-between gap-3 mb-3"><h2 id="list-title" class="h5 m-0">Reservation list</h2><div><label for="filter" class="visually-hidden">Filter reservations by status</label><select class="form-select form-select-sm" id="filter"><option value="all">All statuses</option><option value="Reserved">Reserved</option><option value="In use">In use</option><option value="Draft">Draft</option></select></div></div><div class="table-responsive border rounded"><table class="table table-hover mb-0"><caption class="px-3">Fictional records. New entries stay in this browser tab.</caption><thead class="table-light"><tr><th scope="col">Equipment</th><th scope="col">Date</th><th scope="col">Status</th></tr></thead><tbody id="rows"><tr data-status="Reserved"><th scope="row" class="fw-medium">Camera kit A<div class="small fw-normal text-body-secondary">Mia Chen</div></th><td>10 Oct</td><td><span class="badge text-primary-emphasis bg-primary-subtle">Reserved</span></td></tr><tr data-status="In use"><th scope="row" class="fw-medium">Lighting studio<div class="small fw-normal text-body-secondary">Alex Kim</div></th><td>10 Oct</td><td><span class="badge text-success-emphasis bg-success-subtle">In use</span></td></tr><tr data-status="Draft"><th scope="row" class="fw-medium">Audio recorder<div class="small fw-normal text-body-secondary">Jules Davis</div></th><td>11 Oct</td><td><span class="badge text-secondary-emphasis bg-secondary-subtle">Draft</span></td></tr></tbody></table></div><p id="empty" class="alert alert-info mt-3" hidden>No reservations match this status.</p><p id="results" class="small text-body-secondary mt-2" aria-live="polite">3 reservations shown</p><div class="alert alert-primary mt-4 mb-0"><strong>Try the system</strong><p class="small mb-0 mt-1">Switch color mode, filter the table, submit an empty form, then review a complete reservation in a Bootstrap modal.</p></div></section>
<section class="col-lg-5" aria-labelledby="form-title"><div class="card"><div class="card-body p-3 p-md-4"><h2 id="form-title" class="h5 mb-3">New reservation</h2><form id="reservation" novalidate><div id="error-summary" class="alert alert-danger" tabindex="-1" role="alert" hidden><strong>Check the reservation details.</strong><ul class="mb-0 mt-2" id="error-links"></ul></div><div class="mb-3"><label class="form-label" for="equipment">Equipment</label><select class="form-select" id="equipment" aria-describedby="equipment-error" required><option value="">Choose equipment</option><option>Camera kit A</option><option>Lighting studio</option><option>Audio recorder</option></select><div id="equipment-error" class="invalid-feedback">Choose equipment for this reservation.</div></div><div class="mb-3"><label class="form-label" for="owner">Reserved by</label><input class="form-control" id="owner" autocomplete="name" aria-describedby="owner-hint owner-error" required><div class="form-text" id="owner-hint">Use a fictional name for this example.</div><div class="invalid-feedback" id="owner-error">Enter the name of the person reserving equipment.</div></div><div class="mb-3"><label class="form-label" for="date">Reservation date</label><input class="form-control" id="date" type="date" aria-describedby="date-error" required><div class="invalid-feedback" id="date-error">Choose a reservation date.</div></div><button type="submit" class="btn btn-primary w-100">Review reservation</button></form><p class="small text-body-secondary mt-3 mb-0">This example validates input locally. It does not reserve real equipment.</p></div></div></section></div><div id="notice" class="alert alert-success mt-4 demo-status" role="status" hidden></div></main>
<div class="modal fade" id="review-modal" tabindex="-1" aria-labelledby="review-title" aria-hidden="true"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h2 class="modal-title fs-5" id="review-title">Review reservation</h2><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close review"></button></div><div class="modal-body"><dl class="row mb-0"><dt class="col-4">Equipment</dt><dd class="col-8" id="review-equipment"></dd><dt class="col-4">Reserved by</dt><dd class="col-8" id="review-owner"></dd><dt class="col-4">Date</dt><dd class="col-8" id="review-date"></dd></dl><p class="small text-body-secondary mt-3 mb-0">Confirming adds a row to this local example only.</p></div><div class="modal-footer"><button class="btn btn-outline-secondary" data-bs-dismiss="modal" type="button">Edit details</button><button class="btn btn-primary" id="confirm" type="button">Add to example</button></div></div></div></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script><script>
const $=id=>document.getElementById(id);const fields=['equipment','owner','date'];const review=bootstrap.Modal.getOrCreateInstance($('review-modal'));
$('theme').onclick=()=>{const dark=document.documentElement.dataset.bsTheme!=='dark';document.documentElement.dataset.bsTheme=dark?'dark':'light';$('theme').setAttribute('aria-pressed',String(dark));$('theme').textContent=dark?'Light mode':'Dark mode'};
function filter(){let count=0;for(const row of $('rows').rows){row.hidden=$('filter').value!=='all'&&row.dataset.status!==$('filter').value;if(!row.hidden)count++}$('empty').hidden=count>0;$('results').textContent=count+' reservations shown'}$('filter').onchange=filter;
function validateField(id){const el=$(id),invalid=!el.checkValidity();el.classList.toggle('is-invalid',invalid);el.setAttribute('aria-invalid',String(invalid));return !invalid}
$('reservation').onsubmit=e=>{e.preventDefault();const invalid=fields.filter(id=>!validateField(id));$('error-links').replaceChildren();$('error-summary').hidden=invalid.length===0;if(invalid.length){for(const id of invalid){const li=document.createElement('li'),a=document.createElement('a');a.href='#'+id;a.className='alert-link';a.textContent=$(id+'-error').textContent;a.onclick=e=>{e.preventDefault();$(id).focus()};li.append(a);$('error-links').append(li)}$('error-summary').focus();return}for(const id of fields)$('review-'+id).textContent=$(id).value;review.show()};
for(const id of fields)$(id).addEventListener('input',()=>{if($(id).getAttribute('aria-invalid')==='true')validateField(id)});
$('review-modal').addEventListener('hidden.bs.modal',()=>$('reservation').querySelector('button').focus());
$('confirm').onclick=()=>{const row=document.createElement('tr');row.dataset.status='Reserved';const name=document.createElement('th');name.scope='row';name.className='fw-medium';name.textContent=$('equipment').value;const owner=document.createElement('div');owner.className='small fw-normal text-body-secondary';owner.textContent=$('owner').value;name.append(owner);const date=document.createElement('td');date.textContent=$('date').value;const state=document.createElement('td'),badge=document.createElement('span');badge.className='badge text-primary-emphasis bg-primary-subtle';badge.textContent='Reserved';state.append(badge);row.append(name,date,state);$('rows').prepend(row);$('count').textContent=$('rows').rows.length;$('filter').value='all';filter();review.hide();$('notice').hidden=false;$('notice').textContent='Reservation added to this local example. No data was sent.';$('reservation').reset();for(const id of fields){$(id).classList.remove('is-invalid');$(id).removeAttribute('aria-invalid')}};
</script></body></html>
```

Справочник по коду

- Форма не отправляется в сервис. Подтверждённые бронирования существуют только в течение сеанса этой страницы.

- В локальном примере используются те же закреплённые версии CSS и JavaScript; в этой копии задействованы их общедоступные URL CDN.

### Метка поля, подсказка и явное состояние ошибки

В этой автономной композиции используются стили Bootstrap и настоящий результат проверки. В примере страницы для трёх полей предусмотрена сводка ошибок со ссылками, на которые можно перевести фокус. Одной красной рамки недостаточно, чтобы сообщить, что нужно исправить.

```
<form id="reservation" novalidate>
  <label for="owner" class="form-label">Reserved by</label>
  <input id="owner" class="form-control" required
    aria-describedby="owner-hint owner-error">
  <div id="owner-hint" class="form-text">Use a fictional name.</div>
  <div id="owner-error" class="invalid-feedback">Enter a name.</div>
  <button class="btn btn-primary mt-3" type="submit">Review reservation</button>
</form>
<script>
const form = document.querySelector('#reservation');
const input = document.querySelector('#owner');
form.addEventListener('submit', event => {
  event.preventDefault();
  const invalid = !input.checkValidity();
  input.classList.toggle('is-invalid', invalid);
  input.setAttribute('aria-invalid', String(invalid));
  if (invalid) input.focus();
});
</script>
```

Справочник по коду

- .is-invalid можно задавать явно, не используя .was-validated.

- aria-describedby связывает текст подсказки и ошибки с полем; aria-invalid указывает его текущее состояние.

- В документации предупреждается, что одной лишь пользовательской визуальной индикации ошибки недостаточно для вспомогательных технологий.

### Нативное модальное окно проверки с понятной меткой

В модальном окне используются настоящий плагин Bootstrap, фон, обработка клавиши Escape и управление фокусом. Поместите заголовок в modal-header, проверяемые данные — в modal-body, а действия для продолжения — в modal-footer.

```
<button class="btn btn-primary" data-bs-toggle="modal"
  data-bs-target="#review">Review reservation</button>
<div class="modal fade" id="review" tabindex="-1"
  aria-labelledby="review-title" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h2 class="modal-title fs-5" id="review-title">Review reservation</h2>
        <button class="btn-close" data-bs-dismiss="modal"
          aria-label="Close review"></button>
      </div>
      <div class="modal-body">Camera kit A · 10 October</div>
      <div class="modal-footer">
        <button class="btn btn-outline-secondary" data-bs-dismiss="modal">Edit details</button>
      </div>
    </div>
  </div>
</div>
```

Справочник по коду

- Подключите соответствующий bundle Bootstrap JavaScript один раз.

- data API открывает статический пример; в работающей форме бронирования после успешной проверки используется Modal.getOrCreateInstance.

- Используйте shown.bs.modal для поведения, которое должно запускаться после завершения перехода открытия.

### Адаптивная композиция списка и формы

При контрольной точке lg список оборудования занимает семь столбцов, а форма — пять. Ниже lg оба раздела располагаются друг под другом. g-4 задаёт промежуток между элементами композиции в 1.5rem. Столбцы определяют ширину, а семантические разделы и заголовки описывают содержимое.

```
<main class="container py-4">
  <div class="row g-4">
    <section class="col-lg-7" aria-labelledby="reservations-title">
      <h2 id="reservations-title" class="h5">Reservations</h2>
      <div class="table-responsive">
        <table class="table table-hover">
          <caption>Fictional equipment reservations</caption>
          <thead><tr><th scope="col">Equipment</th><th scope="col">Status</th></tr></thead>
          <tbody><tr><th scope="row">Camera kit A</th><td>Reserved</td></tr></tbody>
        </table>
      </div>
    </section>
    <section class="col-lg-5" aria-labelledby="new-title">
      <h2 id="new-title" class="h5">New reservation</h2>
    </section>
  </div>
</main>
```

Справочник по коду

- Эту же сетку можно настроить с col-md-*, если содержимое действительно помещается на более ранней контрольной точке.

- Используйте приведённую выше таблицу контрольных точек, а не медиазапросы с переменными CSS: var() не может задавать порог медиазапроса.

## Настройка AI-агента дизайн-системы Bootstrap

### Отправная точка для реализации

Для этого полного примера HTML не требуется этап сборки. Он импортирует Bootstrap 5.3.8 из закреплённых URL CDN, указанных в файле. В примерах ниже отдельно показаны отдельные шаблоны из этой работающей страницы.

```
# Save the complete index.html from Component Examples in a new folder.
# Serve that folder with Python 3:
python3 -m http.server 8000
# Open http://localhost:8000/ in a browser.
```

### Запрос для вашего проекта

```
Создайте интерфейс бронирования оборудования на основе Bootstrap 5.3.8 и этого руководства. Используйте строку g-4 с col-lg-7 и col-lg-5, отступы p-3 p-md-4, учитывающие тему роли цветов фона и текста для приглушённого и акцентного содержимого, семантическую таблицу и поля формы с метками. Перед открытием нативного модального окна Bootstrap Modal выполняйте проверку с явными сообщениями об ошибках и сводкой. При редактировании сохраняйте введённые данные; добавляйте записи только в локальное состояние демонстрации, если не предоставлен настоящий API. Поддерживайте светлую и тёмную темы data-bs-theme и закрытие с клавиатуры. Не заменяйте заданную шкалу произвольными значениями.
```

## Дизайн-система Bootstrap: источники и область применения

Руководство по приложению Bootstrap 5.3.8 для OpenDesign и запускаемый пример с нативными компонентами. Справочные значения взяты из документации Bootstrap по ссылкам и закреплённого скомпилированного CSS. Записи о бронированиях, компоновка и сводка проверки — оригинальный код приложения; реальные бронирования не отправляются.

- Справочник Bootstrap 5.3 Версионируемые основы, утилиты и компоненты.

- Переменные и значения по умолчанию CSS Имена и значения по умолчанию, используемые в таблицах спецификации.

- Проверка и поведение модального окна Рекомендации по состояниям полей; в примерах компонентов также приведены ссылки на соответствующие страницы API.

## Связанные материалы дизайн-системы Bootstrap

### Bulma

Создайте редакционный рабочий стол на основе реальной структуры полей и элементов управления Bulma, адаптивных столбцов, семантических модификаторов цвета и переменных CSS, добавив полный код валидации.

### Chakra UI

Справочник по Chakra UI v3: токены, семантические роли цветов, рецепты и составные компоненты форм. Изучите реальные шкалы отступов и типографики, а затем попробуйте встроенную форму профиля рабочего пространства с валидацией, имитацией ошибки сохранения и светлым и тёмным оформлением.

### CoreUI

Очередь проверки CoreUI с реальными переменными темы 5.9, встроенными вкладками и групповым выбором флажками, а также закреплённым уведомлением, позволяющим отменить последнее локальное архивирование.


- [Справочник по реализации](https://getbootstrap.com/docs/5.3/getting-started/introduction/)
- [Источник](https://getbootstrap.com/docs/5.3/customize/css-variables/)
- [Источник](https://getbootstrap.com/docs/5.3/content/typography/)
- [Источник](https://getbootstrap.com/docs/5.3/utilities/spacing/)
- [Источник](https://getbootstrap.com/docs/5.3/layout/grid/)
- [Источник](https://getbootstrap.com/docs/5.3/components/buttons/)
- [Источник](https://getbootstrap.com/docs/5.3/customize/color-modes/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/getting-started/introduction/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/customize/sass/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/customize/sass/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/customize/color-modes/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/customize/color-modes/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/components/buttons/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/components/buttons/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/content/typography/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/utilities/colors/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/utilities/colors/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/utilities/spacing/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/utilities/spacing/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/layout/grid/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/forms/form-control/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/forms/form-control/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/forms/validation/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/content/tables/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/content/tables/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/components/modal/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/components/modal/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/getting-started/vite/)
- [Прочитать вспомогательную спецификацию](https://getbootstrap.com/docs/5.3/getting-started/javascript/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/getting-started/introduction/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/forms/validation/)
- [Справочник по коду](https://getbootstrap.com/docs/5.3/layout/grid/)
- [Справочник Bootstrap 5.3 Версионируемые основы, утилиты и компоненты.](https://getbootstrap.com/docs/5.3/)
- [Переменные и значения по умолчанию CSS Имена и значения по умолчанию, используемые в таблицах спецификации.](https://getbootstrap.com/docs/5.3/customize/css-variables/)
- [Проверка и поведение модального окна Рекомендации по состояниям полей; в примерах компонентов также приведены ссылки на соответствующие страницы API.](https://getbootstrap.com/docs/5.3/forms/validation/)
