Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ html-элСмСнт <dialog>?

Π’ Ρ…ΠΎΠ΄Π΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ часто приходится ΠΏΠΈΡΠ°Ρ‚ΡŒ собствСнныС ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΆΠ΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ часто ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΌ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠΌ, ΠΈ ΠΈΡ… рСализация Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ написания слоТной нСстандартизированной Π»ΠΎΠ³ΠΈΠΊΠΈ. Π’ Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»Π³ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ для Π±Π°Π·ΠΎΠ²Ρ‹Ρ… UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹Π΅ ΠΎΠΊΠ½Π°, использовались самописныС Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, Π° Π² тяТёлых случаях ΠΈ встроСнныС Π² JavaScript ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ alert(), prompt() ΠΈ confirm().

ΠžΡ‚Π»ΠΈΡ‡Π½Π°Ρ Π½ΠΎΠ²ΠΎΡΡ‚ΡŒ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ с использованиСм Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ HTML-элСмСнта <dialog>, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ встроСн Π² стандарт HTML5 ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ Π²ΠΎ всСх соврСмСнных Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ….

Π’ статусС Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ Ρ‡Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊΠ° W3C Ρ‚Π΅Π³ <dialog> появился Π² ΠΌΠ°Π΅ 2013-Π³ΠΎ Π³ΠΎΠ΄Π° вмСстС с Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ элСмСнтами, ΠΊΠ°ΠΊ <details> ΠΈ <summary>, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹ΠΌΠΈ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ классичСских интСрфСйсных Π·Π°Π΄Π°Ρ‡. Π‘ 2014-Π³ΠΎ Π³ΠΎΠ΄Π° <dialog> Π±Ρ‹Π» доступСн Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ… Google Chrome ΠΈ Opera, Π° Π² Firefox ΠΈ Safari полноцСнная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° появилась лишь Π² ΠΌΠ°Ρ€Ρ‚Π΅ 2022-Π³ΠΎ Π³ΠΎΠ΄Π°. По этой ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ <dialog> довольно Ρ€Π΅Π΄ΠΊΠΎ использовался Π² Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…. Однако с ΡƒΡ‡Ρ‘Ρ‚ΠΎΠΌ ΠΏΠΎΡ‡Ρ‚ΠΈ Π΄Π²ΡƒΡ…Π»Π΅Ρ‚Π½Π΅ΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ основными Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ, стандарт стал достаточно устойчивым, Ρ‡Ρ‚ΠΎΠ±Ρ‹ с ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ самописныС <div class="modal" tabindex="-1" role="dialog" aria-modal="true"> Π½Π° Π½Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ познакомимся с возмоТностями <dialog> ΠΏΠΎΠ±Π»ΠΈΠΆΠ΅.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ особСнности использования

HTML-Ρ‚Π΅Π³ <dialog> создаёт скрытоС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ Π½Π° страницС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π²ΡƒΡ… Ρ€Π΅ΠΆΠΈΠΌΠ°Ρ…: Π² качСствС Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΠΎΠΏ-Π°ΠΏΠ° ΠΈΠ»ΠΈ Π² Ρ€ΠΎΠ»ΠΈ модального ΠΎΠΊΠ½Π°.

Π’ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΠΏ-Π°ΠΏΡ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для ΠΏΠΎΠΊΠ°Π·Π° нСнавязчивых ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ сообщСния ΠΎΠ± использовании Π½Π° сайтС Ρ„Π°ΠΉΠ»ΠΎΠ² cookie, автоматичСски ΠΈΡΡ‡Π΅Π·Π°ΡŽΡ‰ΠΈΡ… toast-сообщСний, Ρ‚ΡƒΠ»Ρ‚ΠΈΠΏΠΎΠ² ΠΈ Π΄Π°ΠΆΠ΅ элСмСнтов, ΠΈΠΌΠΈΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… контСкстноС мСню, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ΠΌ ΠΏΡ€Π°Π²ΠΎΠΉ клавиши ΠΌΡ‹ΡˆΠΈ.

ΠœΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠΊΠ½Π° ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡Π΅. Π­Ρ‚ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ увСдомлСния ΠΈ прСдупрСТдСния, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ подтвСрТдСния дСйствий Π½Π° страницС, слоТныС ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΡ‹, ΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, лайтбоксы для просмотра ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ Π²ΠΈΠ΄Π΅ΠΎΡ€ΠΎΠ»ΠΈΠΊΠΎΠ².

Π’ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠΏ-Π°ΠΏ Π½Π΅ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΈΡŽ со страницСй, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ модального ΠΎΠΊΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ открываСтся ΠΏΠΎΠ²Π΅Ρ€Ρ… всСго Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, затСмняСт Ρ„ΠΎΠ½ Π²ΠΎΠΊΡ€ΡƒΠ³ сСбя ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π»ΡŽΠ±Ρ‹Π΅ дСйствия с ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ. Π­Ρ‚Π° Π»ΠΎΠ³ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π±Π΅Π· нСобходимости Π² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… стилях ΠΈ скриптах; СдинствСнноС ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΎΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся для открытия Π΄ΠΈΠ°Π»ΠΎΠ³Π°.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ для открытия Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°

β€” Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠΏ-Π°ΠΏ:

<dialog id="pop-up">ΠŸΡ€ΠΈΠ²Π΅Ρ‚, я ΠΏΠΎΠΏ-Π°ΠΏ!</dialog>
const popUpElement = document.getElementById("pop-up");

popUpElement.show();

β€” модальноС ΠΎΠΊΠ½ΠΎ:

<dialog id="modal">ΠŸΡ€ΠΈΠ²Π΅Ρ‚, Π° я β€” ΠΌΠΎΠ΄Π°Π»ΠΊΠ°!</dialog>
сonst modalElement = document.getElementById("modal");

modalElement.showModal();

Π’ ΠΎΠ±ΠΎΠΈΡ… случаях ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΎΠΊΠ½Π° Ρ‚Π΅Π³Ρƒ <dialog> проставляСтся Π±ΡƒΠ»Π΅Π²Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ open Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ true. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° ΠΌΠΎΠΆΠ½ΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π² true Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π² этом случаС Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ откроСтся ΠΊΠ°ΠΊ ΠΏΠΎΠΏ-Π°ΠΏ β€” Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½ΠΈΠΌ ΠΊΠ°ΠΊ с ΠΌΠΎΠ΄Π°Π»ΠΊΠΎΠΉ просто Π½Π΅ получится. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ для Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΊΠΎΠ½ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄. Для создания ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΏΠΎΠΏ-Π°ΠΏΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ ΠΈ Π±Π΅Π· JS:

<dialog open>ΠŸΡ€ΠΈΠ²Π΅Ρ‚, я ΠΏΠΎΠΏ-Π°ΠΏ!</dialog>

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅:

Бпособы закрытия Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°

Π—Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹Π΅ ΠΎΠΊΠ½Π° ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ, нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΠ½ΠΈ Π±Ρ‹Π»ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹. Π’ΠΎΡ‚ нСсколько способов Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π΅ ΠΈΠ»ΠΈ модальноС ΠΎΠΊΠ½ΠΎ:

β€” Ρ‡Π΅Ρ€Π΅Π· Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° .close():

сonst dialogElement = document.getElementById("dialog");

dialogElement.close();

β€” Ρ‡Π΅Ρ€Π΅Π· ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ†ΠΈΡŽ события submit Π² контСкстС Ρ„ΠΎΡ€ΠΌΡ‹ с Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ method="dialog":

<dialog>
  <h2>Π—Π°ΠΊΡ€ΠΎΠΉ мСня!</h2>

  <form method="dialog">
    <button>Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ</button>
  </form>
</dialog>

β€” Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ΠΌ клавиши Esc:

Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ клавиши Esc Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΊΠΎΠ½. ΠŸΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ‚Π°ΠΊΠΈΠΌ способом сначала запускаСтся событиС cancel, ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡ‚ΠΎΠΌ close β€” Ρ‚Π°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„ΠΎΡ€ΠΌΠ΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ Π½Π΅ сохранятся.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅:

  • Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ close: https://codepen.io/alexgriss/pen/GRzwjaV
  • Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° Ρ‡Π΅Ρ€Π΅Π· submit Ρ„ΠΎΡ€ΠΌΡ‹: https://codepen.io/alexgriss/pen/jOdQVNV
  • Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ Ρ‡Π΅Ρ€Π΅Π· Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ Esc: https://codepen.io/alexgriss/pen/KKJrNKW
  • ΠŸΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ закрытия ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ ΠΏΠΎ Esc Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΠ΅ события cancel: https://codepen.io/alexgriss/pen/mdvQObN

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ

ΠŸΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° Ρ‡Π΅Ρ€Π΅Π· Ρ„ΠΎΡ€ΠΌΡƒ с Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ method="dialog" ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π΅ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ, которая Π±Ρ‹Π»Π° Π½Π°ΠΆΠ°Ρ‚Π° ΠΏΠ΅Ρ€Π΅Π΄ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ΠΌ. Π­Ρ‚ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Ссли послС наТатия Ρ€Π°Π·Π½Ρ‹Ρ… Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… ΠΊΠ½ΠΎΠΏΠΎΠΊ трСбуСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ дСйствия Π½Π° страницС. Для этого ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ свойству элСмСнта Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° returnValue, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° value Ρ‚ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π½Π°ΠΆΠ°Π» ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΎΠΊΠ½ΠΎ.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅: https://codepen.io/alexgriss/pen/ZEwmBKx

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΡƒ Ρ€Π°Π±ΠΎΡ‚Ρ‹

Рассмотрим Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΡƒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° ΠΈ Π΄Π΅Ρ‚Π°Π»ΠΈ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

ΠœΠ΅Ρ…Π°Π½ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΠΎΠΏ-Π°ΠΏΠ°

Если элСмСнт <dialog> Π±Ρ‹Π» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ ΠΊΠ°ΠΊ Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠΏ-Π°ΠΏ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ .show() ΠΈΠ»ΠΈ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° open, Π΄Π²ΠΈΠΆΠΎΠΊ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° автоматичСски размСстит ΠΏΠΎΠΏ-Π°ΠΏ Π² Π²ΠΈΠ΄Π΅ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ спозиционированного Π±Π»ΠΎΡ‡Π½ΠΎΠ³ΠΎ элСмСнта Π² Ρ‚ΠΎΠΌ мСстС, Π³Π΄Π΅ ΠΎΠ½ Π±Ρ‹Π» ΡƒΠΊΠ°Π·Π°Π½ Π² DOM. Для этого элСмСнта Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½Ρ‹ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ CSS-стили, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ отступы ΠΈ Π³Ρ€Π°Π½ΠΈΡ†Ρ‹, Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ фокусируСмый элСмСнт Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠΊΠ½Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ фокус автоматичСски Ρ‡Π΅Ρ€Π΅Π· Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ autofocus. ΠŸΡ€ΠΈ этом сохранится Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ взаимодСйствия с ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ страницы.

ΠœΠ΅Ρ…Π°Π½ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ модального ΠΎΠΊΠ½Π°

МодальноС ΠΎΠΊΠ½ΠΎ устроСно ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ нСсколько слоТнСС, Ρ‡Π΅ΠΌ ΠΏΠΎΠΏ-Π°ΠΏ.

ΠŸΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°

ΠŸΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ модального ΠΎΠΊΠ½Π° с использованиСм ΠΌΠ΅Ρ‚ΠΎΠ΄Π° .showModal() элСмСнт <dialog> рСндСрится Π² ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ слоС HTML-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°. Π­Ρ‚ΠΎΡ‚ слой ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ всю ΡˆΠΈΡ€ΠΈΠ½Ρƒ ΠΈ высоту Π²ΠΈΠ΄ΠΈΠΌΠΎΠΉ области страницы, Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡΡΡŒ ΠΏΠΎΠ²Π΅Ρ€Ρ… всСго Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°. Π’Π°ΠΊΠΎΠΉ слой называСтся Π²Π΅Ρ€Ρ…Π½ΠΈΠΌ слоСм Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° (top layer), ΠΈ являСтся Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠ΅ΠΉ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° β€” Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΈΠΌ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π’ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Ρ… Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ…, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Google Chrome, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ модальноС ΠΎΠΊΠ½ΠΎ рСндСрится Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ DOM-ΡƒΠ·Π»Π΅ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ слоя, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Π² инспСкторС элСмСнтов:

top layer
top layer

ΠŸΠΎΠ½ΡΡ‚ΠΈΠ΅ слоёв относится ΠΊ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ контСкста налоТСния (stacking context), ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰Π΅ΠΉ, ΠΊΠ°ΠΊ элСмСнты Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π° вдоль оси Z ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ, находящСмуся ΠΏΠ΅Ρ€Π΅Π΄ экраном. НапримСр, ΠΏΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ значСния CSS-свойства z-index для элСмСнта, ΠΌΡ‹ создаём Π·Π°ΠΌΠΊΠ½ΡƒΡ‚Ρ‹ΠΉ Π½Π° этом элСмСнтС контСкст налоТСния. Π’Π°ΠΊ позиция элСмСнта Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ Π΅Π³ΠΎ сосСдСй, Π° всС значСния z-index Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… контСкста налоТСния родитСля. Π’Π°ΠΊΡƒΡŽ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ контСкстов налоТСния ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² Π²ΠΈΠ΄Π΅ слоистой структуры, Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ модальноС ΠΎΠΊΠ½ΠΎ всСгда Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π½Π°Π²Π΅Ρ€Ρ…Ρƒ этой ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ рСндСрится Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ слоС, ΠΈ для Π½Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ CSS-ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ z-index.

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ stacking context ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π½Π° mdn .

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ Ρ‚ΠΎ, ΠΊΠ°ΠΊΠΈΠ΅ элСмСнты рСндСрятся Π² top layer β€” Π½Π° mdn .

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°

Когда элСмСнт модального ΠΎΠΊΠ½Π° рСндСрится Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ слоС, ΠΏΠΎΠ΄ Π½ΠΈΠΌ создаётся псСвдо-элСмСнт ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ ::backdrop, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π²ΠΈΠ΄ΠΈΠΌΠΎΠΉ области Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°. Π­Ρ‚Π° ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠ° Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ дСйствия Π½Π° ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ страницС, Π΄Π°ΠΆΠ΅ Ссли для Π½Π΅Ρ‘ установлСно CSS-ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ pointer-events: none.

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… дСйствий обСспСчиваСтся ΠΏΡƒΡ‚Ρ‘ΠΌ автоматичСской установки глобального Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° inert для всСх элСмСнтов, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ модального ΠΎΠΊΠ½Π°. Атрибут inert ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ срабатываниС событий ΠΊΠ»ΠΈΠΊΠ° ΠΈ фокусировки Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… элСмСнтов, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ установлСн, Π° Ρ‚Π°ΠΊΠΆΠ΅ прячСт ΠΈΡ… ΠΎΡ‚ экранных Π΄ΠΈΠΊΡ‚ΠΎΡ€ΠΎΠ² (скринридСров) ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ (accessibility).

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ inert: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert

ПовСдСниС фокуса

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ фокусируСмый элСмСнт Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ автоматичСски ΠΏΠΎΠΏΠ°Π΄Ρ‘Ρ‚ Π² фокус Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π΅Ρ‘ открытия. Для измСнСния элСмСнта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ фокус, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ autofocus ΠΈΠ»ΠΈ tabindex. Установка tabindex для элСмСнта Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½, Π² любом случаС, являСтся СдинствСнным элСмСнтом страницы, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½Π΅ примСняСтся Π»ΠΎΠ³ΠΈΠΊΠ° Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° inert.

ΠŸΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° фокус возвращаСтся Π½Π° Ρ‚ΠΎΡ‚ элСмСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π·Π²Π°Π» Π΅Π³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅.

РСшСниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ взаимодСйствия с ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΠΊΠ½Π°ΠΌΠΈ

К соТалСнию, нативная рСализация элСмСнта <dialog> Π½Π΅ ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ всС аспСкты взаимодСйствия с ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΠΊΠ½Π°ΠΌΠΈ. Π”Π°Π»Π΅Π΅, я ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ основных UX-ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΈ использовании ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΊΠΎΠ½.

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° скролла

Π₯отя Π² Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ модального ΠΎΠΊΠ½Π° ΠΈ создаётся псСвдоэлСмСнт ::backdrop, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ находится ΠΏΠΎΠ²Π΅Ρ€Ρ… страницы ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ взаимодСйствиС с ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ β€” скролл страницы всё Π΅Ρ‰Ρ‘ доступСн. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, поэтому ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ модального ΠΎΠΊΠ½Π° рСкомСндуСтся ΠΎΠ±Ρ€Π΅Π·Π°Ρ‚ΡŒ содСрТимоС body:

body {
  overflow: hidden;
}

Π’Π°ΠΊΠΎΠ΅ css-ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ придётся динамичСски Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΡƒΠ±ΠΈΡ€Π°Ρ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ модального ΠΎΠΊΠ½Π°. Π­Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ ΠΏΡƒΡ‚Ρ‘ΠΌ манипуляции классом, содСрТащим Π΄Π°Π½Π½ΠΎΠ΅ CSS-ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ:

// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ
document.body.classList.add("scroll-lock");

// ΠŸΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΌΠΎΠ΄Π°Π»ΠΊΠΈ
document.body.classList.remove("scroll-lock");

Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ сСлСктором :has, Ссли статус ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ этого сСлСктора соотвСтствуСт трСбованиям ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°:

body:has(dialog[open]) {
  overflow: hidden;
}

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅: https://codepen.io/alexgriss/pen/XWOyVKj

Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³Π° ΠΏΠΎ ΠΊΠ»ΠΈΠΊΡƒ Π½Π° свободной области

Π­Ρ‚ΠΎ стандартный UX-сцСнарий для модального ΠΎΠΊΠ½Π° ΠΈ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ нСсколькими способами. ΠŸΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ с двумя способами Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹:

Бпособ, основанный Π½Π° особСнностях Ρ€Π°Π±ΠΎΡ‚Ρ‹ псСвдоэлСмСнта ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ ::backdrop

Клик ΠΏΠΎ псСвдоэлСмСнту ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ рассматриваСтся ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠΊ ΠΏΠΎ самому элСмСнту Π΄ΠΈΠ°Π»ΠΎΠ³Π°. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ссли вСсь ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ модального ΠΎΠΊΠ½Π° ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ <div> ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΈΠΌ сам элСмСнт Π΄ΠΈΠ°Π»ΠΎΠ³Π°, ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΊΡƒΠ΄Π° Π±Ρ‹Π» Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ ΠΊΠ»ΠΈΠΊ β€” Π½Π° ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΡƒ ΠΈΠ»ΠΈ Π½Π° содСрТимоС модального ΠΎΠΊΠ½Π°.

НС Π·Π°Π±ΡƒΠ΄Π΅ΠΌ ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ стандартныС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½Ρ‹Π΅ стили отступов ΠΈ Π³Ρ€Π°Π½ΠΈΡ† Ρƒ элСмСнта <dialog>, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ модального ΠΎΠΊΠ½Π° ΠΏΡ€ΠΈ случайном ΠΊΠ»ΠΈΠΊΠ΅ ΠΏΠΎ Π½ΠΈΠΌ:

dialog {
  padding: 0;
  border: none;
}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΡΡ‚ΠΈΠ»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΎΠ±Ρ‰ΠΈΡ… для ΠΎΠΊΠ½Π° Π³Ρ€Π°Π½ΠΈΡ† ΠΈ отступов ΠΌΡ‹ примСняСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ΅.

ΠžΡΡ‚Π°Π»ΠΎΡΡŒ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ модальноС ΠΎΠΊΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π½Π° ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΡƒ, Π° Π½Π΅ Π½Π° Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ элСмСнт ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈ:

const handleModalClick = ({ currentTarget, target }) => {
  const isClickedOnBackdrop = target === currentTarget;

  if (isClickedOnBackdrop) {
    currentTarget.close();
  }
};

modalElement.addEventListener("click", handleModalClick);

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅: https://codepen.io/alexgriss/pen/mdvQXpJ

Бпособ, основанный Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ способа, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π» обёртывания Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ содСрТимого модального ΠΎΠΊΠ½Π° Π² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ элСмСнт, этот способ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ использования Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈ. Всё, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, β€” это ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, выходят Π»ΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ курсора Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ области элСмСнта ΠΎΠΊΠ½Π° ΠΏΡ€ΠΈ ΠΊΠ»ΠΈΠΊΠ΅:

const handleModalClick = (event) => {
  const modalRect = modalElement.getBoundingClientRect();

  if (
    event.clientX < modalRect.left ||
    event.clientX > modalRect.right ||
    event.clientY < modalRect.top ||
    event.clientY > modalRect.bottom
  ) {
    modalElement.close();
  }
};

modalElement.addEventListener("click", handleModalClick);

ΠŸΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π΅Π»Π΅: https://codepen.io/alexgriss/pen/NWoePVP

Бтилизация Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… HTML-элСмСнтов, элСмСнт <dialog> прСдоставляСт Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π² ΠΏΠ»Π°Π½Π΅ стилизации. Π’ΠΎΡ‚ нСсколько Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ² для стилизации Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹Ρ… ΠΎΠΊΠΎΠ½:

Бтилизация Ρ„ΠΎΠ½Π° ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ Ρ‡Π΅Ρ€Π΅Π· сСлСктор ::backdrop: https://codepen.io/alexgriss/pen/ExrOQEO

АнимированноС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΎΠΊΠ½Π°: https://codepen.io/alexgriss/pen/QWYJQJO

МодальноС ΠΎΠΊΠ½ΠΎ Π² Π²ΠΈΠ΄Π΅ сайдбара: https://codepen.io/alexgriss/pen/GRzwxgr

Π”ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ

Π₯отя Π΄ΠΎΠ»Π³ΠΎΠ΅ врСмя элСмСнт <dialog> ΠΈΠΌΠ΅Π» Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с соотвСтствиСм стандартам доступности (accessibility), Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ основныС Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ экранныС Π΄ΠΈΠΊΡ‚ΠΎΡ€Ρ‹ (VoiceOver, TalkBack, NVDA), Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹ΠΌΠΈ ΠΎΠΊΠ½Π°ΠΌΠΈ.

ΠŸΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ элСмСнта <dialog>, фокус экранного Π΄ΠΈΠΊΡ‚ΠΎΡ€Π° пСрСводится Π½Π° Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ, Π° Π² случаС с ΠΌΠΎΠ΄Π°Π»ΠΊΠΎΠΉ β€” остаётся Π² Π΅Ρ‘ ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π°.

Нативный элСмСнт <dialog> ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ распознаётся Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ тСхнологиями ΠΊΠ°ΠΊ элСмСнт с ARIA-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ role="dialog". Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ <dialog>, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΊΠ°ΠΊ модальноС ΠΎΠΊΠ½ΠΎ, Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ элСмСнт с ARIA-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ aria-modal="true".

Π’ΠΎΡ‚ нСсколько Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΉ, ΠΊΠ°ΠΊ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ элСмСнта <dialog>:

aria-labelledby

ВсСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹Ρ… ΠΎΠΊΠΎΠ½ ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ aria-labelledby для элСмСнта <dialog>, со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°:

<dialog aria-labelledby="dialog-header">
  <h1 id="dialog-header">Dialog Header</h1>
</dialog>

Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС экранныС Π΄ΠΈΠΊΡ‚ΠΎΡ€Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Ρ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ содСрТимоС этого Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°.

aria-describedby

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ aria-describedby для связи с содСрТимым Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°. НСкоторыС скринридСры Π½Π΅ смогут ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ содСрТимоС элСмСнта <dialog> Π±Π΅Π· этого Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΈ Π»ΡŽΠ±Ρ‹Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ элСмСнты для управлСния состояниСм Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ вынСсСны ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ элСмСнта с содСрТимым:

<dialog aria-labelledby="dialog-header" aria-describedby="dialog-content">
  <h1 id="dialog-header">Dialog Header</h1>

  <div id="dialog-content">Dialog Content</div>

  <button id="close-btn">Close dialog</button>
</dialog>

aria-label

ВсСгда добавляйтС ΠΊΠ½ΠΎΠΏΠΊΡƒ для закрытия Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹Ρ… ΠΎΠΊΠΎΠ½, особСнно Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠΎΠ΄Π°Π»ΠΎΠΊ. Для Π»ΡƒΡ‡ΡˆΠ΅ΠΉ доступности Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ элСмСнт <button>. Для ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ содСрТат ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΉ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ тСкст, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ этот тСкст Π² ARIA-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π΅ aria-label:

<dialog aria-labelledby="dialog-header">
  <button id="close-btn" aria-label="Close dialog">x</button>

  <h1 id="dialog-header">Dialog Header</h1>
</dialog>

БраузСрная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Нативный элСмСнт Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° прСдставляСт собой ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΈ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ стандартных интСрфСйсных Π·Π°Π΄Π°Ρ‡. К соТалСнию, Π΅Π³ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π² основных Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ… Π±Ρ‹Π»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΡΡ€Π°Π²Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅Π΄Π°Π²Π½ΠΎ, ΠΈ Π² Π±ΠΎΠ»Π΅Π΅ экзотичСских ΠΈΠ»ΠΈ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ… ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ всё Π΅Ρ‰Ρ‘ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ Π±Ρ‹Ρ‚ΡŒ. ΠŸΡ€ΠΈ отсутствии ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ элСмСнта <dialog>, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»ΠΈΡ„ΠΈΠ»ΠΎΠΌ , Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Google Chrome.

Π‘ΠΊΡ€ΠΈΠΏΡ‚Ρ‹ ΠΈ стили ΠΏΠΎΠ»ΠΈΡ„ΠΈΠ»Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ локально, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ CDN ΠΈΠ»ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΊΠ°ΠΊ npm-Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ: npm install dialog-polyfill.

Если ΠΏΠΎΠ»ΠΈΡ„ΠΈΠ» ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Ρ‘Π½ Π½Π΅ Ρ‡Π΅Ρ€Π΅Π· ΠΈΠΌΠΏΠΎΡ€Ρ‚ npm-ΠΏΠ°ΠΊΠ΅Ρ‚Π°, Π½Π΅ Π·Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ стили: https://github.com/GoogleChrome/dialog-polyfill/blob/master/dist/dialog-polyfill.css

Если трСбуСтся ΡΡ‚ΠΈΠ»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ псСвдоэлСмСнт ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ модального ΠΎΠΊΠ½Π° ::backdrop, ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ примСняСтС стили ΠΊ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ элСмСнту с классом .backdrop для обСспСчСния совмСстимости с Π±ΠΎΠ»Π΅Π΅ старыми Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ:

dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
}

dialog + .backdrop {
  background-color: rgba(0, 0, 0, 0.5);
}

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΠΈΡ„ΠΈΠ» рСкомСндуСтся Ρ‡Π΅Ρ€Π΅Π· динамичСский ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ‚Π΅Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ элСмСнт <dialog>:

const isBrowserNotSupportDialog = window.HTMLDialogElement === undefined;

if (isBrowserNotSupportDialog) {
  const dialogElement = document.getElementById("modal");

  const { default: polyfill } = await import("dialog-polyfill");

  polyfill.registerDialog(dialogElement);
}

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Нативный HTML-элСмСнт <dialog> β€” это ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ простой ΠΈ ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΊΠΎΠ½ ΠΈ ΠΏΠΎΠΏ-Π°ΠΏΠΎΠ². Он ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ поддСрТиваСтся соврСмСнными Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… Π½Π° чистом JS, Ρ‚Π°ΠΊ ΠΈ Π² контСкстС любого Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°.

Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΎΡ…Π²Π°Ρ‚ΠΈΠ»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚Π΅ΠΌΡ‹:

  • ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠ·Π²Π°Π½ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ элСмСнт <dialog>;
  • ВзаимодСйствиС с API элСмСнта <dialog>;
  • ΠœΠ΅Ρ…Π°Π½ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹ΠΌΠΈ ΠΎΠΊΠ½Π°ΠΌΠΈ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°;
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΌΠΎΠ΄Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΠΊΠ½Π°ΠΌΠΈ ΠΈ ΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ;
  • Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ доступности элСмСнта <dialog> для Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… устройств, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ скринридСры;
  • Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ элСмСнта <dialog>.

НапослСдок ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ°ΡŽ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° модального ΠΎΠΊΠ½Π° Π½Π° чистом JS, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡƒΡ‡Ρ‚Π΅Π½Ρ‹ основныС аспСкты, описанныС Π² ΡΡ‚Π°Ρ‚ΡŒΠ΅: https://codepen.io/alexgriss/pen/abXPOPP

Π­Ρ‚ΠΎ всё, Ρ‡Ρ‚ΠΎ я Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ Ρ€Π°ΡΡΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΡ€ΠΎ особСнности Ρ€Π°Π±ΠΎΡ‚Ρ‹ с HTML-элСмСнтом <dialog>. НадСюсь, Ρ‡Ρ‚ΠΎ данная ΡΡ‚Π°Ρ‚ΡŒΡ Π²Π΄ΠΎΡ…Π½ΠΎΠ²ΠΈΡ‚ вас Π½Π° экспСримСнты!


ΠŸΡ€ΠΈΠ³Π»Π°ΡˆΠ°ΡŽ вас ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° ΠΌΠΎΠΉ Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»: https://t.me/alexgriss , Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ я ΠΏΠΈΡˆΡƒ ΠΎ Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅, ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΡŽ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹, дСлюсь своим ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΌΠ½Π΅Π½ΠΈΠ΅ΠΌ ΠΈ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽ Ρ‚Π΅ΠΌΡ‹, Π²Π°ΠΆΠ½Ρ‹Π΅ для ΠΊΠ°Ρ€ΡŒΠ΅Ρ€Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.