Модальное окно
Используйте модальный JavaScript плагин Bootstrap для добавления диалоговых окнон на ваш сайт для лайтбоксов, уведомлений пользователей или полностью настраиваемого контента.
Как это работает
До того как начать работу с модальными компонентами Bootstrap, ознакомьтесь со следующей информацией, т.к. параметры недавно изменились.
- Модальные окна сделаны на HTML, CSS и JavaScript. Они располагаются поверх всего документа и блокируют прокрутку тела документа
<body>
, вместо него прокручивая модальные окна - Клик вне модального элемента автоматически закрывает его.
- Bootstrap позволяет активировать лишь один модальный элемент за раз. Вложенные модальные элементы не поддерживаются, т.к. мы думаем, что они принесли бы неудобства.
- Модальные элементы имеют
position: fixed
, что может вызвать иногда их частичную отрисовку. Мы рекомендуем размещать модальные элементы на самом верху страницы, когда возможно, для избегания сбоев и влияния других элементов на корректную работу модальных элементов.modal
. - Опять же – из-за
position: fixed
есть некоторые сложности при использовании их на мобильных устройствах. Смотри документацию поддержки в браузерах. - Из-за семантики HTML5 атрибут
autofocus
не работает с модальными элементами Bootstrap. Чтобы добиться такого же эффекта, используйте собственный JavaScript:
const myModal = document.getElementById('myModal')
const myInput = document.getElementById('myInput')
myModal.addEventListener('shown.bs.modal', () => {
myInput.focus()
})
prefers-reduced-motion
. Смотрите раздел специальных возможностей в нашей документации по редукции анимации.
Далее – демонстрация примеров и инструкции по использованию.
Примеры
Модальные компоненты
Ниже приведен пример статического модального окна (это означает, что его position
и display
были переопределены). Включены модальный заголовок, модальное тело (требуется для padding
) и модальный нижний колонтитул (необязательно). Мы просим вас по возможности включать модальные заголовки с действиями по отклонению или предоставить другое явное действие по отклонению.
<div class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Заголовок модального окна</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
<p>Здесь идет основной текст модального окна</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary">Сохранить изменения</button>
</div>
</div>
</div>
</div>
«Живое» демо
Переключите рабочую модальную демонстрацию, нажав кнопку ниже. Он будет скользить вниз и исчезать из верхней части страницы.
<!-- Кнопка-триггер модального окна -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Запустите демо модального окна
</button>
<!-- Модальное окно -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Заголовок модального окна</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary">Сохранить изменения</button>
</div>
</div>
</div>
</div>
Статический фон
Когда фон установлен на статический, модальное окно не будет закрываться при нажатии за его пределами. Нажмите кнопку ниже, чтобы попробовать.
<!-- Кнопка-триггер модального окна -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
Запустить модальное окно со статическим фоном
</button>
<!-- Модальное окно -->
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Заголовок модального окна</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary">Понял</button>
</div>
</div>
</div>
</div>
Прокрутка длинного содержимого
Когда модальные окна становятся слишком длинными для области просмотра или устройства пользователя, они прокручиваются независимо от самой страницы. Попробуйте демонстрацию ниже, чтобы понять, что мы имеем в виду.
Вы также можете создать прокручиваемое модальное окно, которое позволяет прокручивать модальное тело, добавляя .modal-dialog-scrollable
к .modal-dialog
.
<!-- Прокручиваемое модальное окно -->
<div class="modal-dialog modal-dialog-scrollable">
...
</div>
Вертикальное центрирование
Добавьте .modal-dialog-centered
к .modal-dialog
для вертикального центрирования модального окна.
<!-- Вертикально центрированное модальное окно -->
<div class="modal-dialog modal-dialog-centered">
...
</div>
<!-- Вертикально центрированное прокручиваемое модальное окно -->
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
...
</div>
Всплывающие подсказки и возникающие подсказки
Всплывающие подсказки и всплывающие подсказки могут быть помещены в модальные окна по мере необходимости. Когда модальные окна закрываются, любые всплывающие подсказки и всплывающие окна также автоматически закрываются.
<div class="modal-body">
<h5>Поповер в модальном окне</h5>
<p>Эта <a href="#" role="button" class="btn btn-secondary" data-bs-toggle="popover" title="Popover title" data-bs-content="Popover body content is set in this attribute.">кнопка</a> вызывает всплывающее окно при нажатии.</p>
<hr>
<h5>Подсказки в модальном окне</h5>
<p><a href="#" data-bs-toggle="tooltip" title="Tooltip">Эта ссылка</a> и <a href="#" data-bs-toggle="tooltip" title="Tooltip">эта ссылка</a> имеет всплывающие подсказки при наведении.</p>
</div>
Использование сетки
Используйте сеточную систему Bootstrap в модальном окне, вложив .container-fluid
в .modal-body
. Затем используйте обычные классы системы сетки, как и везде.
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
</div>
<div class="row">
<div class="col-md-3 ms-auto">.col-md-3 .ms-auto</div>
<div class="col-md-2 ms-auto">.col-md-2 .ms-auto</div>
</div>
<div class="row">
<div class="col-md-6 ms-auto">.col-md-6 .ms-auto</div>
</div>
<div class="row">
<div class="col-sm-9">
Level 1: .col-sm-9
<div class="row">
<div class="col-8 col-sm-6">
Level 2: .col-8 .col-sm-6
</div>
<div class="col-4 col-sm-6">
Level 2: .col-4 .col-sm-6
</div>
</div>
</div>
</div>
</div>
</div>
Комбинируйте содержимое модальных элементов
Есть много кнопок, которые все запускают один модальный элемент со слегка разным содержимым? Используйте event.relatedTarget
и атрибуты data-bs-*
для изменения содержимого в зависимости от нажатой кнопки.
Ниже – пример демо с кодом HTML и JavaScript. Для информации по relatedTarget
читайте инфо по событиям модальных элементов.
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@mdo">Открыть модальное окно для @mdo</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@fat">Открыть модальное окно для @fat</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@getbootstrap">Открыть модальное окно для @getbootstrap</button>
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Новое сообщение</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="recipient-name" class="col-form-label">Получатель:</label>
<input type="text" class="form-control" id="recipient-name">
</div>
<div class="mb-3">
<label for="message-text" class="col-form-label">Сообщение:</label>
<textarea class="form-control" id="message-text"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary">Отправить сообщение</button>
</div>
</div>
</div>
</div>
const exampleModal = document.getElementById('exampleModal')
exampleModal.addEventListener('show.bs.modal', event => {
// Кнопка, которая активировала модальное окно
const button = event.relatedTarget
// Извлекает информацию из атрибутов data-bs-*
const recipient = button.getAttribute('data-bs-whatever')
// При необходимости вы можете инициировать запрос AJAX здесь,
// а затем выполнить обновление в обратном вызове.
//
// Обновляет содержимое модального окна.
const modalTitle = exampleModal.querySelector('.modal-title')
const modalBodyInput = exampleModal.querySelector('.modal-body input')
modalTitle.textContent = `New message to ${recipient}`
modalBodyInput.value = recipient
})
Переключение между модальными окнами
<div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalToggleLabel">Модалка 1</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
Покажите второе модальное окно и скройте его с помощью кнопки ниже.
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-bs-target="#exampleModalToggle2" data-bs-toggle="modal">Открыть второе модальное окно</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="exampleModalToggle2" aria-hidden="true" aria-labelledby="exampleModalToggleLabel2" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalToggleLabel2">Модалка 2</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
Скройте это модальное окно и покажите первое с помощью кнопки ниже.
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal">Вернуться к первому</button>
</div>
</div>
</div>
</div>
<a class="btn btn-primary" data-bs-toggle="modal" href="#exampleModalToggle" role="button">Открыть первое модальное окно</a>
Изменение анимации
Переменная $modal-fade-transform
определяет состояние преобразования .modal-dialog
перед анимацией постепенного появления, переменная $modal-show-transform
определяет преобразование .modal-dialog
в конце модального появления анимация.
Если вы хотите, например, анимацию увеличения, вы можете установить $modal-fade-transform: scale(.8)
.
Анимация при удалении
Для модальных окон, которые просто появляются, а не исчезают при просмотре, удалите класс .fade
из Вашей модальной разметки.
<div class="modal" tabindex="-1" aria-labelledby="..." aria-hidden="true">
...
</div>
Динамическая высота
Если высота модального окна изменяется, пока он открыт, Вы должны вызвать myModal.handleUpdate()
, чтобы скорректировать положение модального окна в случае появления полосы прокрутки.
Доступность
Не забудьте добавить aria-labelledby="..."
, ссылаясь на Заголовок модального окна, в .modal
. Кроме того, Вы можете дать описание Вашего модального диалога с помощью aria-describedby
в .modal
. Обратите внимание, что Вам не нужно добавлять role="dialog"
, поскольку мы уже добавляем его через JavaScript..
Встраивание видео из YouTube
Встраивание видео YouTube в модальные окна требует дополнительного JavaScript не в Bootstrap для автоматической остановки воспроизведения и т.д. См. этот полезный пост о переполнении стека для получения дополнительной информации.
Дополнительные размеры
Модальные окна имеют три необязательных размера, доступных через классы модификаторов, которые помещаются в .modal-dialog
. Эти размеры действуют в определенных контрольных точках, чтобы избежать горизонтальных полос прокрутки на более узких окнах просмотра.
Размер | Класс | Максимальная ширина модального окна |
---|---|---|
Маленький | .modal-sm |
300px |
По умолчанию | Нет | 500px |
Большой | .modal-lg |
800px |
Очень большой | .modal-xl |
1140px |
Наш модальный класс по умолчанию без модификатора представляет собой модальное окно «среднего» размера.
<div class="modal-dialog modal-xl">...</div>
<div class="modal-dialog modal-lg">...</div>
<div class="modal-dialog modal-sm">...</div>
Полноэкранная модаль
Другое переопределение - это возможность вывести модальное окно, охватывающее область просмотра пользователя, доступное через классы модификаторов, которые помещаются в .modal-dialog
.
Класс | Доступность | |
---|---|---|
.modal-fullscreen |
Всегда | |
.modal-fullscreen-sm-down |
576px |
|
.modal-fullscreen-md-down |
768px |
|
.modal-fullscreen-lg-down |
992px |
|
.modal-fullscreen-xl-down |
1200px |
|
.modal-fullscreen-xxl-down |
1400px |
<!-- Полноэкранное модальное окно -->
<div class="modal-dialog modal-fullscreen-sm-down">
...
</div>
CSS
Переменные
Добавлено в версии 5.2.0Как часть развивающегося подхода Bootstrap к переменным CSS, модальные окна теперь используют локальные переменные CSS в .modal
и .modal-backdrop
для расширенной настройки в реальном времени. Значения переменных CSS задаются через Sass, поэтому настройка Sass по-прежнему поддерживается.
--#{$prefix}modal-zindex: #{$zindex-modal};
--#{$prefix}modal-width: #{$modal-md};
--#{$prefix}modal-padding: #{$modal-inner-padding};
--#{$prefix}modal-margin: #{$modal-dialog-margin};
--#{$prefix}modal-color: #{$modal-content-color};
--#{$prefix}modal-bg: #{$modal-content-bg};
--#{$prefix}modal-border-color: #{$modal-content-border-color};
--#{$prefix}modal-border-width: #{$modal-content-border-width};
--#{$prefix}modal-border-radius: #{$modal-content-border-radius};
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
--#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
--#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
--#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
--#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
--#{$prefix}modal-header-border-color: #{$modal-header-border-color};
--#{$prefix}modal-header-border-width: #{$modal-header-border-width};
--#{$prefix}modal-title-line-height: #{$modal-title-line-height};
--#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
--#{$prefix}modal-footer-bg: #{$modal-footer-bg};
--#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
--#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
--#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
--#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
--#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
Переменные Sass
$modal-inner-padding: $spacer;
$modal-footer-margin-between: .5rem;
$modal-dialog-margin: .5rem;
$modal-dialog-margin-y-sm-up: 1.75rem;
$modal-title-line-height: $line-height-base;
$modal-content-color: null;
$modal-content-bg: $white;
$modal-content-border-color: var(--#{$prefix}border-color-translucent);
$modal-content-border-width: $border-width;
$modal-content-border-radius: $border-radius-lg;
$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width);
$modal-content-box-shadow-xs: $box-shadow-sm;
$modal-content-box-shadow-sm-up: $box-shadow;
$modal-backdrop-bg: $black;
$modal-backdrop-opacity: .5;
$modal-header-border-color: var(--#{$prefix}border-color);
$modal-header-border-width: $modal-content-border-width;
$modal-header-padding-y: $modal-inner-padding;
$modal-header-padding-x: $modal-inner-padding;
$modal-header-padding: $modal-header-padding-y $modal-header-padding-x; // Keep this for backwards compatibility
$modal-footer-bg: null;
$modal-footer-border-color: $modal-header-border-color;
$modal-footer-border-width: $modal-header-border-width;
$modal-sm: 300px;
$modal-md: 500px;
$modal-lg: 800px;
$modal-xl: 1140px;
$modal-fade-transform: translate(0, -50px);
$modal-show-transform: none;
$modal-transition: transform .3s ease-out;
$modal-scale-transform: scale(1.02);
Цикл
Адаптивные полноэкранные модальные окна генерируются с помощью карты $breakpoints
и цикла в scss/_modal.scss
.
@each $breakpoint in map-keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
$postfix: if($infix != "", $infix + "-down", "");
@include media-breakpoint-down($breakpoint) {
.modal-fullscreen#{$postfix} {
width: 100vw;
max-width: none;
height: 100%;
margin: 0;
.modal-content {
height: 100%;
border: 0;
@include border-radius(0);
}
.modal-header,
.modal-footer {
@include border-radius(0);
}
.modal-body {
overflow-y: auto;
}
}
}
}
Использование
Модальный плагин переключает ваш скрытый контент по запросу с помощью атрибутов данных или JavaScript. Он также переопределяет поведение прокрутки по умолчанию и генерирует .modal-backdrop
, чтобы предоставить область клика для отклонения отображаемых модальных окон при щелчке вне модального окна.
Через атрибуты данных
Переключение
Активируйте модальное окно без написания JavaScript. Установите data-bs-toggle="modal"
на элемент контроллера, например кнопку, вместе с data-bs-target="#foo"
или href="#foo"
для нацеливания на конкретное модальное окно для переключения.
<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Запустить модальное окно</button>
Отклонение
Отклонение может быть достигнуто с помощью атрибута data
на кнопке внутри modal, как показано ниже:
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
или на кнопке за пределами modal с помощью data-bs-target
, как показано ниже:
<button type="button" class="btn-close" data-bs-dismiss="modal" data-bs-target="#my-modal" aria-label="Закрыть"></button>
Через JavaScript
Создайте модальное окно с одной строкой JavaScript:
const myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
// or
const myModalAlternative = new bootstrap.Modal('#myModal', options)
Опции
Параметры можно передавать через атрибуты данных или JavaScript. Для атрибутов данных добавьте имя параметра к data-bs-
, как в data-bs-animation=""
. Не забудьте изменить тип регистра имени параметра с camelCase на kebab-case при передаче параметров через атрибуты данных. Например, используйте data-bs-custom-class="beautifier"
вместо data-bs-customClass="beautifier"
.
Начиная с Bootstrap 5.2.0, все компоненты поддерживают экспериментальный зарезервированный атрибут данных data-bs-config
, который может содержать простую конфигурацию компонента в виде строки JSON. Когда элемент имеет атрибуты data-bs-config='{"delay":0, "title":123}'
и data-bs-title="456"
, окончательное значение title
будет 456
, а отдельные атрибуты данных переопределяют значения, указанные в data-bs-config
. Кроме того, существующие атрибуты данных могут содержать значения JSON, такие как data-bs-delay='{"show":0,"hide":150}'
.
Название | Тип | По умолчанию | Описание |
---|---|---|---|
backdrop |
boolean, 'static' |
true |
Включает элемент модального фона. В качестве альтернативы укажите static для фона, который не закрывает модальное окно при нажатии. |
keyboard |
boolean | true |
Закрывает модальное окно при нажатии клавиши escape. |
focus |
boolean | true |
Ставит фокус на модальное окно при инициализации. |
Методы
Асинхронные методы и переходы
Все методы API асинхронны и запускают переход. Они возвращаются к вызывающей стороне, как только переход начинается, но до его завершения. Кроме того, вызов метода переходного компонента будет проигнорирован.
Дополнительную информацию см. в нашей документации по JavaScript.
Варианты прохождения
Активирует Ваш контент как модальное окно. Принимает необязательные параметры object
.
const myModal = new bootstrap.Modal('#myModal', {
keyboard: false
})
Метод | Описание |
---|---|
toggle |
Вручную переключает модальное окно. Возврат к вызывающей стороне до того, как модальное окно было действительно показано или скрыто (т.е. до того, как произошло событие shown.bs.modal или hidden.bs.modal ). |
show |
Вручную открывает модальное окно. Возврат к вызывающей стороне до того, как модальное окно действительно будет показано (т.е. до того, как произойдет событие shown.bs.modal ). Кроме того, вы можете передать элемент DOM в качестве аргумента, который может быть получен в модальных событиях (как свойство relatedTarget ). (т.е. const modalToggle = document.getElementById('toggleMyModal'); myModal.show(modalToggle) |
hide |
Вручную скрывает модальное окно. Возврат к вызывающей стороне до того, как модальное окно будет фактически скрыто (т.е. до того, как произойдет событие hidden.bs.modal ). |
handleUpdate |
Вручную отрегулируйте положение модального окна, если высота модального окна изменяется, когда оно открыто (например, в случае появления полосы прокрутки). |
dispose |
Уничтожает модальное окно элемента. (Удаляет сохраненные данные в элементе DOM) |
getInstance |
Статический метод, позволяющий получить модальный экземпляр, связанный с элементом DOM. |
getOrCreateInstance |
Статический метод, который позволяет вам получить модальный экземпляр, связанный с элементом DOM, или создать новый, если он не был инициализирован. |
События
Модальный класс Bootstrap предоставляет несколько событий для подключения к модальным функциям. Все модальные события запускаются в самом модальном окне (то есть в <div class="modal">
).
Событие | Описание |
---|---|
show.bs.modal |
Это событие срабатывает немедленно при вызове метода экземпляра show . Если это вызвано щелчком, элемент, по которому щелкнули, доступен как свойство relatedTarget . |
shown.bs.modal |
Это событие запускается, когда модальное окно становится видимым для пользователя (будет ждать завершения переходов CSS). Если это вызвано щелчком, элемент, по которому щелкнули, доступен как свойство relatedTarget . |
hide.bs.modal |
Это событие запускается сразу после вызова метода экземпляра hide . |
hidden.bs.modal |
Это событие запускается, когда модальное окно больше не скрыто от пользователя (будет ждать завершения переходов CSS). |
hidePrevented.bs.modal |
Это событие запускается, когда отображается модальное окно, его фон является static и выполняется щелчок за пределами модального окна. Событие также запускается, когда нажата клавиша escape, а для параметра keyboard установлено значение false . |
const myModalEl = document.getElementById('myModal')
myModalEl.addEventListener('hidden.bs.modal', event => {
// сделайте что-нибудь...
})