Spec-Zone.ru › HTML

<dialog>: Элемент диалогового окна

Базовая версия 2022

Новое

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

  • Подробнее
  • Полная совместимость
  • Отправить отзыв

Элемент <dialog> HTML представляет собой модальное или немодальное диалоговое окно или другой интерактивный компонент, такой как всплывающее сообщение, инспектор или дочернее окно.

Элемент HTML <dialog> используется для создания модальных и немодальных диалоговых окон. Модальные диалоговые окна прерывают взаимодействие с остальной частью страницы, делая её неактивной, тогда как немодальные диалоговые окна позволяют взаимодействовать с остальной частью страницы.

Для отображения элемента <dialog> необходимо использовать JavaScript. Используйте метод .showModal() для отображения модального диалогового окна и метод .show() для отображения немодального диалогового окна. Диалоговое окно можно закрыть, используя метод .close() или метод dialog при отправке формы <form>, которая вложена в элемент <dialog>. Модальные диалоговые окна также можно закрыть, нажав клавишу Esc.

Атрибуты

Этот элемент включает в себя глобальные атрибуты.

Предупреждение: Атрибут tabindex не должен использоваться с элементом <dialog>. См. примечания по использованию.

open

Указывает, что диалоговое окно активно и доступно для взаимодействия. Если атрибут open не задан, диалоговое окно не будет отображаться пользователю. Рекомендуется использовать метод .show() или метод .showModal() для рендеринга диалоговых окон, а не атрибут open. Если диалоговое окно открыто с помощью атрибута <dialog>, оно является немодальным.

Примечание: Хотя вы можете переключаться между открытым и закрытым состоянием немодальных диалоговых окон, переключая наличие атрибута open, этот подход не рекомендуется.

Примечания по использованию

  • Элементы HTML <form> могут быть использованы для закрытия диалогового окна, если у них есть атрибут method="dialog" или если кнопка, используемая для отправки формы, имеет значение атрибута formmethod="dialog". При отправке формы <form> внутри элемента <dialog> с помощью метода dialog, диалоговое окно закрывается, состояние элементов управления формой сохраняется, но не отправляется, и свойство returnValue получает значение нажатой кнопки.
  • Псевдоэлемент CSS ::backdrop может использоваться для стилизации фона модального диалогового окна, которое отображается за элементом <dialog> при отображении диалогового окна с помощью метода HTMLDialogElement.showModal(). Например, этот псевдоэлемент можно использовать для размытия, затемнения или иного затемнения содержимого за модальным диалоговым окном.
  • Атрибут autofocus должен быть добавлен к элементу, с которым, по ожиданиям, пользователь должен немедленно взаимодействовать после открытия модального диалогового окна. Если ни один другой элемент не предполагает более непосредственного взаимодействия, рекомендуется добавить атрибут autofocus к кнопке закрытия внутри диалогового окна или к самому диалоговому окну, если ожидается, что пользователь щелкнет/активирует его, чтобы закрыть его.
  • Не добавляйте свойство tabindex к элементу <dialog>, так как он не является интерактивным и не получает фокус. Содержимое диалогового окна, включая кнопку закрытия, содержащуюся в диалоговом окне, может получить фокус и быть интерактивным.

Доступность

При реализации диалогового окна важно учитывать наиболее подходящее место для установки фокуса пользователя. При использовании HTMLDialogElement.showModal() для открытия диалогового окна, фокус устанавливается на первом вложенном фокусируемом элементе. Явное указание начальной позиции фокуса с помощью атрибута autofocus поможет гарантировать, что начальный фокус устанавливается на элементе, который считается лучшим начальным фокусом для конкретного диалогового окна. В случае сомнений, поскольку может быть неизвестно, где можно установить начальный фокус внутри диалогового окна, особенно в случаях, когда содержимое диалогового окна динамически отображается при вызове, сам элемент <dialog> может обеспечить лучшую начальную позицию фокуса.

Убедитесь, что имеется механизм, позволяющий пользователям закрывать диалоговое окно. Наиболее надёжным способом обеспечения возможности закрытия диалогового окна всеми пользователями является включение явной кнопки, такой как кнопка подтверждения, отмены или закрытия.

По умолчанию диалоговое окно, вызываемое методом showModal() , может быть закрыто нажатием клавиши Esc. Немодальное диалоговое окно по умолчанию не закрывается клавишей Esc, и в зависимости от того, что представляет собой немодальное диалоговое окно, такое поведение может быть нежелательным. Пользователи, использующие клавиатуру, ожидают, что клавиша Esc закроет модальные диалоговые окна; убедитесь, что это поведение реализовано и поддерживается. Если открыто несколько модальных диалоговых окон, нажатие клавиши Esc должно закрывать только последнее отображаемое диалоговое окно. При использовании <dialog>, это поведение обеспечивает браузер.

Хотя диалоговые окна можно создавать с помощью других элементов, собственный элемент <dialog> предоставляет функции удобства использования и доступности, которые необходимо воспроизвести, если вы используете другие элементы для аналогичной цели. Если вы создаёте собственную реализацию диалогового окна, убедитесь, что поддерживаются все ожидаемые по умолчанию поведения и соблюдаются рекомендации по маркировке.

Элемент <dialog> отображается браузерами аналогично настраиваемым диалоговым окнам, которые используют атрибут ARIA role="dialog". Элементы <dialog> , вызываемые методом showModal() , неявно имеют aria-modal="true", в то время как элементы <dialog> , вызываемые методом show() или отображаемые с помощью атрибута open или путём изменения значения display элемента <dialog> , отображаются как [aria-modal="false"]. При реализации модальных диалоговых окон всё, кроме элемента <dialog> и его содержимого, должно быть сделано неактивным с помощью атрибута inert. При использовании <dialog> вместе с методом HTMLDialogElement.showModal() это поведение обеспечивает браузер.

Примеры

Диалоговое окно только HTML

В этом примере показано создание немодального диалогового окна только с помощью HTML. Из-за булевого атрибута open в элементе <dialog> диалоговое окно отображается открытым при загрузке страницы. Диалоговое окно можно закрыть, нажав кнопку «ОК», так как атрибут method в элементе <form> имеет значение "dialog". В этом случае нет необходимости в JavaScript для закрытия формы.

html
<dialog open>
  <p>Greetings, one and all!</p>
  <form method="dialog">
    <button>OK</button>
  </form>
</dialog>

Результат

Примечание: Перезагрузите страницу, чтобы сбросить вывод.

Это диалоговое окно изначально открыто из-за наличия атрибута open . Диалоговые окна, которые отображаются с помощью атрибута open , являются немодальными. После нажатия «ОК» диалоговое окно закрывается, оставляя фрейм «Результат» пустым. При закрытии диалогового окна нет предоставленного метода для его повторного открытия. По этой причине предпочтительный метод отображения немодальных диалоговых окон — использование метода HTMLDialogElement.show(). Можно переключать отображение диалогового окна, добавляя или удаляя булевый атрибут open , но это не рекомендуется.

Создание модального диалогового окна

Этот пример демонстрирует модальное диалоговое окно с фоном-градиентом. Метод .showModal() открывает модальное диалоговое окно при активации кнопки "Показать диалог". Диалог можно закрыть, нажав клавишу Esc или вызвав метод close(), когда нажата кнопка "Закрыть" внутри диалога.

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

HTML

html
<dialog>
  <button autofocus>Close</button>
  <p>This modal dialog has a groovy backdrop!</p>
</dialog>
<button>Show the dialog</button>

CSS

Мы можем стилизовать фон диалога, используя псевдоэлемент ::backdrop.

css
::backdrop {
  background-image: linear-gradient(
    45deg,
    magenta,
    rebeccapurple,
    dodgerblue,
    green
  );
  opacity: 0.75;
}

JavaScript

Диалог открывается модально с помощью метода .showModal() и закрывается с помощью метода .close().

js
const dialog = document.querySelector("dialog");
const showButton = document.querySelector("dialog + button");
const closeButton = document.querySelector("dialog button");

// "Show the dialog" button opens the dialog modally
showButton.addEventListener("click", () => {
  dialog.showModal();
});

// "Close" button closes the dialog
closeButton.addEventListener("click", () => {
  dialog.close();
});

Результат

При отображении модального диалога он появляется поверх любых других диалогов, которые могут быть присутствовать. Всё за пределами модального диалога неактивно, и взаимодействия за пределами диалога заблокированы. Обратите внимание, что при открытом диалоге, за исключением самого диалога, взаимодействие с документом невозможно; кнопка "Показать диалог" в основном скрыта почти непрозрачным фоном диалога и неактивна.

Обработка возвращаемого значения диалога

Этот пример демонстрирует свойство returnValue элемента <dialog> и способ закрытия модального диалога с помощью формы. По умолчанию returnValue — это пустая строка или значение кнопки, которая отправляет форму внутри элемента <dialog>, если таковая имеется.

Этот пример открывает модальное диалоговое окно при активации кнопки "Показать диалог". Диалог содержит форму с элементом <select> и двумя элементами <button>, которые по умолчанию type="submit". Обработчик событий обновляет значение кнопки "Подтвердить" при изменении выбора в списке. Если кнопка "Подтвердить" активируется для закрытия диалога, текущее значение кнопки является возвращаемым значением. Если диалог закрывается по нажатию кнопки "Отмена", то returnValue — cancel.

После закрытия диалога возвращаемое значение отображается под кнопкой "Показать диалог". Если диалог закрывается нажатием клавиши Esc, то returnValue не обновляется, и событие close не происходит, поэтому текст в элементе <output> не обновляется.

HTML

html
<!-- A modal dialog containing a form -->
<dialog id="favDialog">
  <form>
    <p>
      <label>
        Favorite animal:
        <select>
          <option value="default">Choose…</option>
          <option>Brine shrimp</option>
          <option>Red panda</option>
          <option>Spider monkey</option>
        </select>
      </label>
    </p>
    <div>
      <button value="cancel" formmethod="dialog">Cancel</button>
      <button id="confirmBtn" value="default">Confirm</button>
    </div>
  </form>
</dialog>
<p>
  <button id="showDialog">Show the dialog</button>
</p>
<output></output>

JavaScript

js
const showButton = document.getElementById("showDialog");
const favDialog = document.getElementById("favDialog");
const outputBox = document.querySelector("output");
const selectEl = favDialog.querySelector("select");
const confirmBtn = favDialog.querySelector("#confirmBtn");

// "Show the dialog" button opens the <dialog> modally
showButton.addEventListener("click", () => {
  favDialog.showModal();
});

// "Cancel" button closes the dialog without submitting because of [formmethod="dialog"], triggering a close event.
favDialog.addEventListener("close", (e) => {
  outputBox.value =
    favDialog.returnValue === "default"
      ? "No return value."
      : `ReturnValue: ${favDialog.returnValue}.`; // Have to check for "default" rather than empty string
});

// Prevent the "confirm" button from the default behavior of submitting the form, and close the dialog with the `close()` method, which triggers the "close" event.
confirmBtn.addEventListener("click", (event) => {
  event.preventDefault(); // We don't want to submit this fake form
  favDialog.close(selectEl.value); // Have to send the select box value here.
});

Результат

Вышеупомянутые примеры демонстрируют три способа закрытия модальных диалогов:

  • Отправкой формы внутри диалога с помощью метода dialog (как показано в примере HTML-только).
  • Нажатием клавиши Esc.
  • Вызовом метода HTMLDialogElement.close() (как показано в примере модального диалога). В этом примере кнопка "Отмена" закрывает диалог с помощью метода формы dialog, а кнопка "Подтвердить" закрывает диалог с помощью метода HTMLDialogElement.close().

Кнопка "Отмена" включает атрибут formmethod="dialog", который переопределяет метод по умолчанию <form> — GET. Когда метод формы dialog, состояние формы сохраняется, но не отправляется, и диалог закрывается.

Без action, отправка формы по методу по умолчанию GET приводит к перезагрузке страницы. Мы используем JavaScript для предотвращения отправки и закрытия диалога с помощью методов event.preventDefault() и HTMLDialogElement.close() соответственно.

Важно предоставить механизм закрытия для каждого элемента dialog. Кнопка Esc по умолчанию не закрывает немодальные диалоги, и нельзя предполагать, что пользователь будет иметь доступ к физической клавиатуре (например, кто-то использует сенсорный экран без доступа к клавиатуре).

Закрытие диалога с обязательным полем ввода формы

Когда форма внутри диалога имеет обязательное поле ввода, пользовательский агент позволит закрыть диалог только после ввода значения в это поле. Для закрытия такого диалога используйте атрибут formnovalidate на кнопке закрытия или вызовите метод close() на объекте диалога при нажатии на кнопку закрытия.

html
<dialog id="dialog">
  <form method="dialog">
    <p>
      <label>
        Favorite animal:
        <input type="text" required />
      </label>
    </p>
    <div>
      <input type="submit" id="normal-close" value="Normal close" />
      <input
        type="submit"
        id="novalidate-close"
        value="Novalidate close"
        formnovalidate />
      <input type="submit" id="js-close" value="JS close" />
    </div>
  </form>
</dialog>
<p>
  <button id="show-dialog">Show the dialog</button>
</p>
<output></output>

JavaScript

js
const showBtn = document.getElementById("show-dialog");
const dialog = document.getElementById("dialog");
const jsCloseBtn = dialog.querySelector("#js-close");

showBtn.addEventListener("click", () => {
  dialog.showModal();
});

jsCloseBtn.addEventListener("click", (e) => {
  e.preventDefault();
  dialog.close();
});

Результат

Из вывода видно, что закрыть диалог с помощью кнопки Обычное закрытие невозможно. Но диалог можно закрыть, если обойти проверку формы, используя атрибут formnovalidate на кнопке Отмена. Программно, dialog.close() также закроет такой диалог.

Анимация диалогов

<dialog> устанавливаются в display: none; при скрытии и display: block; при отображении, а также удаляются из/добавляются в верхний слой и дерево доступности. Следовательно, для того чтобы <dialog> элементы были анимированы, свойство display должно быть анимируемым. Поддерживающие браузеры анимируют display с использованием варианта типа анимации дискретная анимация. Конкретно, браузер будет переключаться между none и другим значением display, чтобы анимируемое содержимое отображалось на протяжении всей анимации.

Например:

  • При анимации display от none до block (или другого видимого значения display) значение переключится на block на 0% от общей длительности анимации, чтобы оно было видимым на всём её протяжении.
  • При анимации display от block (или другого видимого значения display) до none, значение переключится на none на 100% от общей длительности анимации, чтобы оно было видимым на всём её протяжении.

Примечание: При анимации с помощью CSS переходов, transition-behavior: allow-discrete необходимо установить для активации вышеописанного поведения. Это поведение по умолчанию доступно при анимации с помощью CSS анимаций; эквивалентный шаг не требуется.

Переход диалоговых элементов

При анимации <dialog> с помощью CSS переходов требуются следующие функции:

@starting-style правило

Обеспечивает набор начальных значений свойств, установленных на <dialog>, с которого вы хотите перейти каждый раз при его открытии. Это необходимо для избежания неожиданного поведения. По умолчанию CSS переходы происходят только тогда, когда свойство изменяется с одного значения на другое на видимом элементе; они не вызываются при первом обновлении стиля элементов или при изменении типа display с none на другой тип.

display свойство

Добавьте display в список переходов, чтобы <dialog> оставался в виде display: block (или другого видимого значения display установленного в состоянии открытия диалога) на протяжении всего перехода, гарантируя видимость других переходов.

overlay свойство

Включите overlay в список переходов, чтобы обеспечить отложенное удаление <dialog> из верхнего слоя до завершения перехода, снова гарантируя видимость перехода.

transition-behavior свойство

Установите transition-behavior: allow-discrete на display и overlay переходы (или на сокращённую запись transition) для включения дискретных переходов на эти два свойства, которые по умолчанию не анимируются.

Вот быстрый пример того, как это может выглядеть.

HTML

HTML содержит элемент <dialog>, а также кнопку для отображения диалогового окна. Кроме того, элемент <dialog> содержит ещё одну кнопку для закрытия самого себя.

html
<dialog id="dialog">
  Content here
  <button class="close">close</button>
</dialog>

<button class="show">Show Modal</button>
CSS

В CSS мы включаем блок @starting-style, который определяет стили начального перехода для свойств opacity и transform, стили конечного перехода для состояния dialog[open], и стили по умолчанию для состояния dialog для возврата к нему после появления <dialog>. Обратите внимание, как список переходов <dialog> включает не только эти свойства, но и свойства display и overlay, каждое из которых имеет установленное значение allow-discrete.

Мы также устанавливаем начальное значение свойства background-color для свойства ::backdrop, появляющегося за <dialog> при открытии, чтобы обеспечить плавную анимацию затемнения. Селектор dialog[open]::backdrop выбирает только бэкдропы элементов <dialog> при открытии диалогового окна.

css
/*   Open state of the dialog  */
dialog[open] {
  opacity: 1;
  transform: scaleY(1);
}

/*   Closed state of the dialog   */
dialog {
  opacity: 0;
  transform: scaleY(0);
  transition:
    opacity 0.7s ease-out,
    transform 0.7s ease-out,
    overlay 0.7s ease-out allow-discrete,
    display 0.7s ease-out allow-discrete;
  /* Equivalent to
  transition: all 0.7s allow-discrete; */
}

/*   Before-open state  */
/* Needs to be after the previous dialog[open] rule to take effect,
    as the specificity is the same */
@starting-style {
  dialog[open] {
    opacity: 0;
    transform: scaleY(0);
  }
}

/* Transition the :backdrop when the dialog modal is promoted to the top layer */
dialog::backdrop {
  background-color: rgb(0 0 0 / 0%);
  transition:
    display 0.7s allow-discrete,
    overlay 0.7s allow-discrete,
    background-color 0.7s;
  /* Equivalent to
  transition: all 0.7s allow-discrete; */
}

dialog[open]::backdrop {
  background-color: rgb(0 0 0 / 25%);
}

/* This starting-style rule cannot be nested inside the above selector
because the nesting selector cannot represent pseudo-elements. */

@starting-style {
  dialog[open]::backdrop {
    background-color: rgb(0 0 0 / 0%);
  }
}
JavaScript

JavaScript добавляет обработчики событий для кнопок «Показать» и «Закрыть», которые вызывают отображение и закрытие <dialog> при нажатии:

js
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");

showBtn.addEventListener("click", () => {
  dialogElem.showModal();
});

closeBtn.addEventListener("click", () => {
  dialogElem.close();
});
Результат

Код отображается следующим образом:

Примечание: Поскольку <dialog> меняются с display: none на display: block каждый раз при их отображении, <dialog> переходит от своих стилей @starting-style к стилям dialog[open] каждый раз при переходе входа. Когда <dialog> закрывается, он переходит от состояния dialog[open] к состоянию по умолчанию dialog.

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

Анимации диалоговых окон с ключевыми кадрами

При анимации диалогового окна с помощью CSS анимации с ключевыми кадрами есть некоторые различия с переходами:

  • Вы не предоставляете @starting-style.
  • Вы включаете значение display в ключевой кадр; это будет значение display на протяжении всей анимации или до тех пор, пока не будет встречено другое значение отображения, отличное от none.
  • Вам не нужно явно включать дискретную анимацию; нет эквивалента allow-discrete внутри ключевых кадров.
  • Вам также не нужно устанавливать overlay внутри ключевых кадров; анимация display обрабатывает анимацию перехода <dialog> от отображенного к скрытому.

Давайте рассмотрим пример, чтобы вы увидели, как это выглядит.

HTML

Во-первых, HTML содержит элемент <dialog>, а также кнопку для отображения диалогового окна. Кроме того, элемент <dialog> содержит ещё одну кнопку для закрытия самого себя.

html
<dialog id="dialog">
  Content here
  <button class="close">close</button>
</dialog>

<button class="show">Show Modal</button>
CSS

CSS определяет ключевые кадры для анимации между закрытым и открытым состояниями <dialog>, а также анимацию плавного входа для бэкдропа <dialog>. Анимации <dialog> включают анимацию display, чтобы гарантировать, что фактические эффекты видимой анимации останутся видимыми на протяжении всей длительности. Обратите внимание, что анимировать плавное выход затемнения бэкдропа не представлялось возможным — бэкдроп сразу удаляется из DOM при закрытии <dialog>, поэтому нет ничего, что можно анимировать.

css
dialog {
  animation: fade-out 0.7s ease-out;
}

dialog[open] {
  animation: fade-in 0.7s ease-out;
}

dialog[open]::backdrop {
  animation: backdrop-fade-in 0.7s ease-out forwards;
}

/* Animation keyframes */

@keyframes fade-in {
  0% {
    opacity: 0;
    transform: scaleY(0);
    display: none;
  }

  100% {
    opacity: 1;
    transform: scaleY(1);
    display: block;
  }
}

@keyframes fade-out {
  0% {
    opacity: 1;
    transform: scaleY(1);
    display: block;
  }

  100% {
    opacity: 0;
    transform: scaleY(0);
    display: none;
  }
}

@keyframes backdrop-fade-in {
  0% {
    background-color: rgb(0 0 0 / 0%);
  }

  100% {
    background-color: rgb(0 0 0 / 25%);
  }
}

body,
button {
  font-family: system-ui;
}
JavaScript

Наконец, JavaScript добавляет обработчики событий для кнопок, чтобы включить отображение и закрытие <dialog>:

js
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");

showBtn.addEventListener("click", () => {
  dialogElem.showModal();
});

closeBtn.addEventListener("click", () => {
  dialogElem.close();
});
Результат

Код отображается следующим образом:

Техническое резюме

Категории контента Потоковый контент, корневой элемент раздела
Разрешенный контент Потоковый контент
Пропуск тегов Нет, как начальный, так и конечный тег обязательны.
Разрешенные родительские элементы Любой элемент, который принимает потоковый контент
Неявная роль ARIA диалоговое окно
Разрешенные роли ARIA alertdialog
Интерфейс DOM HTMLDialogElement

Спецификации

Спецификация
Стандарт HTML
# the-dialog-element

Совместимость с браузерами

Рабочий стол Мобильный
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on IOS Samsung Internet WebView Android
dialog 37 79 98 24 15.4 37 98 24 15.4 3.0 37
open 37 79 98 24 15.4 37 98 24 15.4 3.0 37

См. также

  • HTMLDialogElement интерфейс
  • close событие
  • cancel событие
  • open свойство интерфейса HTMLDialogElement
  • inert глобальный атрибут для HTML-элементов
  • ::backdrop псевдоэлемент CSS
  • Веб-формы в разделе «Изучение»

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API