Элемент dialog и атрибут popover.
Инструкции к применению

Рома Ахмадуллин, Дром

Элемент dialog
и атрибут popover.
Инструкции к применению

Рома Ахмадуллин
Дром

Рома Ахмадуллин

Модалки и всплывашки

Контролы с дропдауном

Тултипы

Меню

Всплывающие нотификации

Сайдбар

Диалоговые окна

Комбинация

UI-киты

Material UI
Ant Design
Chakra UI

UI-киты – ОК ✅

Как оно работает?

            
            <div class="overlay">...</div>
            <div class="modal">...</div>
            <style>
                .overlay {
                    ...
                }

                .modal {
                    ...
                }
            </style>
            
        

ДОБАВИМ
ЧУТОЧКУ JS

УПС

Что может пойти не так?
или
Что важно учесть?

Характеристика Кастомное решение
Привязка к якорю
            
            new IntersectionObserver(([tooltip]) => {
                // обновляем местоположение элемента руками
            });
            
        
            
            // или с помощью либы
            import magicAutoPlacement from 'super-puper-awesome-lib';
            magicAutoPlacement(tooltip);
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
            
            <div class="overlay"></div>
            <style>
                .overlay {
                    ...
                }
            </style>
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
            
            // явное закрытие 
            closeButton.addEventListener('click', () => {
                modal.classList.remove('visible');
            });
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
            
            // неявное закрытие 
            outsideArea.addEventListener('click', () => {
                sidebar.classList.remove('visible');
            });
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
            
            // закрываем модалку на Escape
            window.addEventListener('keydown', (event) => {
                if (event.key === 'Escape') {
                    modal.classList.remove('visible');
                }
            });
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
            
            // используем либу
            import { createFocusTrap } from 'focus-trap';
            createFocusTrap(modal);
            
        
            
            <!-- расставляем атрибут inert -->
            <div class="modal visible">
                ...
            </div>
            <div class="everything-else" inert>
                ...
            </div>
            
        
Can I use: атрибут inert
            z-index: 9999;
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
            
            <div 
                role="dialog"
                aria-labelledby="modal-label"
                aria-modal="true"
                class="modal visible"
            >
                <h3 id="modal-label">Укажите контактные данные</h3>
            </div>
            
        
Характеристика Кастомное решение
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y

Как-то сложно...

ВОТ БУДУТ У НАС НАТИВНЫЕ МОДАЛКИ

ЗАЖИВЕМ

Хмм...

Давайте разбираться

<dialog>

<dialog>

HTML-элемент для построения диалогов со встроенной ролью dialog и модальными характеристиками.

HTML-спецификация
HTML-спецификация: элемент dialog
Can I use: элемент dialog
            
            <dialog>
                <!-- содержимое диалога -->
            </dialog>
            
        
            
            // открывает диалог в немодальном режиме
            element.show();

            // открывает диалог в модальном режиме
            element.showModal();

            // закрывает диалог
            element.close();
            
        
            
            <dialog open>
                <!-- содержимое диалога -->
            </dialog>
            
        

Что по характеристикам?

Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
top layer

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

CSS-спецификация
CSS-спецификация: top layer

z-index vs top layer

    
        <div class="yellow"></div>
        <div class="green"></div>
        <div class="blue"></div>
    
    

Может ли быть несколько элементов на top layer?

Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
backdrop

Псевдоэлемент, представляющий собой блок размером с вьюпорт, имеющийся у любого элемента, попавшего в top layer.

CSS-спецификация
CSS-спецификация: backdrop
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y

Внешний вид


            /* стили для диалога */
            dialog {
                ...
            }

            /* открытого */
            dialog[open] {
                ...
            }

            /* модального */
            dialog:modal {
                ...
            }

            /* бэкдропа */
            dialog::backdrop {
                ...
            }

Анимация

            
            dialog {
                transition: 
                    opacity .5s ease-in,
                    scale .5s ease-in,
                    display .5s ease-in allow-discrete;
            }
            
        
            
            dialog {
                transition: 
                    opacity .5s ease-in,
                    scale .5s ease-in,
                    display .5s ease-in allow-discrete;
            }
            
        
Can I use: allow discrete
            
                /* открытый диалог */
                dialog {
                    ...
                }
                
                /* открывающийся диалог */
                @starting-style { 
                    dialog {
                        ...
                    }
                }

                /* закрывающийся диалог */
                dialog:not([open]) {
                    ...
                }
            
        
            
            /* открытый диалог */
            dialog {
                opacity: 1;
                scale: 1;
            }
            
        
            
            /* открывающийся диалог */
            @starting-style { 
                dialog {
                    opacity: 0; 
                    scale: 1.1; 
                }
            }
            
        
Can I use: @strating-style
            
            /* закрывающийся диалог */
            dialog:not([open]) {
                opacity: 0;
                scale: .9;
                transition-duration: .4s;
                transition-timing-function: ease;
            }
            
        
            
            @media (prefers-reduced-motion: no-preference) {
                /* css для анимации */
            }
            
        
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y
Характеристика Dialog
show() showModal()
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Вынос на верхний слой
Семантика / a11y

popover

popover

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

HTML-спецификация
HTML-спецификация: атрибут popover
Can I use: Popover API
            
            <div popover>
                <!-- содержимое элемента -->
            </div>
            
        
            
            <button popovertarget="popover-example">
                Показать popover
            </button>
            <div popover id="popover-example">
                Привет! Я поповер!
            </div>
            
        
            
            <button popovertarget="popover-example" popovertargetaction="show">
                Открыть
            </button>
            <button popovertarget="popover-example" popovertargetaction="hide">
                Закрыть
            </button>
            <button popovertarget="popover-example" popovertargetaction="toggle">
                Тоггл
            </button>
            <div popover id="popover-example">
                Привет! Я поповер!
            </div>
            
        
            
            <button popovertarget="popover-example" popovertargetaction="show">
                Открыть
            </button>
            <button popovertarget="popover-example" popovertargetaction="hide">
                Закрыть
            </button>
            <button popovertarget="popover-example" popovertargetaction="toggle">
                Тоггл
            </button>
            <div popover id="popover-example">
                Привет! Я поповер!
            </div>
            
        
            
            // показывает поповер
            element.showPopover();

            // скрывает поповер
            element.hidePopover();

            // переключает видимость (показывает и скрывает)
            element.togglePopover();
            
        
            
            <div popover="auto">
                ...
            </div>
            <div popover="manual">
                ...
            </div>
            
        

Что по характеристикам?

Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
            
            /* стили для поповера */
            [popover] {
               ...
            }

            /* открытого */
            [popover]:popover-open {
                ...
            }
            
            /* бэкдропа */
            [popover]::backdrop {
                ...
            }
            
        
            
            [popover] {
                transition: 
                    opacity .5s, 
                    scale .5s, 
                    translate .5s, 
                    overlay .5s allow-discrete, 
                    display .5s allow-discrete;
            }
            
        
            
            [popover] {
                transition: 
                    opacity .5s, 
                    scale .5s, 
                    translate .5s, 
                    overlay .5s allow-discrete, 
                    display .5s allow-discrete;
            }
            
        
        
            /* открытый поповер */
            [popover]:popover-open {
                ...
            }

            /* открывающийся поповер */
            @starting-style {
                [popover]:popover-open {
                    ...
                }
            }

            /* закрывающийся поповер */
            [popover]:not(:popover-open) {
                ...
            }
        
    
        
            /* бэкдроп открытого поповера */                
            [popover]:popover-open::backdrop {
                ...
            }

            /* бэкдроп открывающегося поповера */       
            @starting-style {
                [popover]:popover-open::backdrop {
                    ...
                }
            }

            /* бэкдроп закрытого поповера */       
            [popover]:not(:popover-open)::backdrop {
                ...
            }
        
    
            
            @media (prefers-reduced-motion: no-preference) {
                /* css для анимации */
            }
            
        
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Popover дает возможность показать контент,
семантику добавляем сами.
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y

Позиционирование поповера

            
            <div class="select">
                <div class="select-box"></div>
                <div class="dropdown"></div>
            </div>
            <style>
                .select {
                    position: relative;
                }
                .dropdown {
                    position: absolute;
                    top: 40px;
                    left: 0;
                }
            </style>
            
        

Позиционирование через JavaScript

            
            <button popovertarget="popover-example">
                ...
            </button>
            <div popover id="popover-example">
                ...
            </div>
            
        
            
            import { 
                computePosition, offset, autoPlacement, autoUpdate 
            } from '@floating-ui/dom';

            const updatePosition = () => {
                computePosition(button, popover, {
                    middleware: [offset(5), autoPlacement()],
                }).then(({x, y}) => {
                    Object.assign(popover.style, {
                        left: `${x}px`,
                        top: `${y}px`,
                    });
                });
            };

            autoUpdate(button, popover, updatePosition);
            
        
            
            [popover] {
                /* сбрасываем дефолтные стили */
                inset: 0;
                margin: 0;
                /* выставляем стили необходимые для работы @floating-ui */
                width: max-content;
                position: absolute;
                top: 0;
                left: 0;
                will-change: transform;
            }
            
        

Многословно

плюс надо тащить дополнительный JavaScript

CSS Anchor Positioning

Can I use: CSS Anchor Positioning
CSS Anchor Positioning Polyfill
            
            <button popovertarget="popover-example">
                ...
            </button>
            <div popover id="popover-example">
                ...
            </div>
            
        

            button[popovertarget="popover-example"] {
                /* даем якорю имя */
                anchor-name: --button-element;
            }

            [popover] {
                inset: unset;
                margin: 10px;
                /* привязываемся к якорю по его имени */
                position-anchor: --button-element;
                /* показываем поповер выше якоря */
                bottom: anchor(top);
                /* выравниваем по центру */
                justify-self: anchor-center;
            }
            
        

            button[popovertarget="popover-example"] {
                /* даем якорю имя */
                anchor-name: --button-element;
            }

            [popover] {
                inset: unset;
                margin: 10px;
                /* привязываемся к якорю по его имени */
                position-anchor: --button-element;
                /* показываем поповер выше якоря */
                bottom: anchor(top);
                /* выравниваем по центру */
                justify-self: anchor-center;
            }
            
        

            button[popovertarget="popover-example"] {
                /* даем якорю имя */
                anchor-name: --button-element;
            }

            [popover] {
                inset: unset;
                margin: 10px;
                /* привязываемся к якорю по его имени */
                position-anchor: --button-element;
                /* показываем поповер выше якоря */
                bottom: anchor(top);
                /* выравниваем по центру */
                justify-self: anchor-center;
            }
            
        

            button[popovertarget="popover-example"] {
                /* даем якорю имя */
                anchor-name: --button-element;
            }

            [popover] {
                inset: unset;
                margin: 10px;
                /* привязываемся к якорю по его имени */
                position-anchor: --button-element;
                /* показываем поповер выше якоря */
                bottom: anchor(top);
                /* выравниваем по центру */
                justify-self: anchor-center;
            }
            
        

            button[popovertarget="popover-example"] {
                /* даем якорю имя */
                anchor-name: --button-element;
            }

            [popover] {
                inset: unset;
                margin: 10px;
                /* привязываемся к якорю по его имени */
                position-anchor: --button-element;
                /* показываем поповер выше якоря */
                bottom: anchor(top);
                /* выравниваем по центру */
                justify-self: anchor-center;
            }
            
        
            
            [popover] {
                bottom: anchor(top);
                justify-self: anchor-center;
            }
            
        
            
            [popover] {
                bottom: anchor(top);
                justify-self: anchor-center;

                /* физическое значение */
                position-area: top;
                /* логическое значение */
                position-area: block-start;
            }
            
        
Anchor position tool
            
            [popover] {
                position-area: top;
                position-try-fallbacks: --bottom;
            }
    
            @position-try --bottom {
                position-area: bottom;
            }
            
        
            
            [popover] {
                position-area: top;
                position-try-fallbacks: --bottom;
            }
    
            @position-try --bottom {
                position-area: bottom;
            }
            
        
            
            [popover] {
                position-area: top;
                position-try-fallbacks: --bottom;
            }
    
            @position-try --bottom {
                position-area: bottom;
            }
            
        
            
            [popover] {
                position-area: top;
                position-try-fallbacks: --bottom;
            }
    
            @position-try --bottom {
                position-area: bottom;
            }
            
        

Хочется красоты 💅

            
            /* добавляем стиля поповеру */
            [popover] {
                background: hsl(0, 0%, 0%);
                color: hsl(0, 0%, 100%);
                overflow: visible;
            }
            
        
            
            /* добавляем хвостик тултипа */
            [popover]::after {
                content: '';
                position: absolute;
                bottom: -5px;
                left: 50%;
                transform: translate(-50%, 0px);
                transform-origin: center top;
                border-style: solid;
                border-width: 5px 5px 0px;
                border-color: hsl(0, 0%, 0%) transparent transparent;
            }
            
        
            
            [popover] {
                /* ссылаемся на якорь, к которому привязан поповер */
                position-anchor: --button-element;
                /* делаем поповер якорем */
                anchor-name: --popover-element;
            }
            /* хвостики */
            [popover]::before, [popover]::after {
                /* якоримся на тот же элемент, что и поповер */
                position-anchor: --button-element;
                content: '';
                position: fixed;
                background: inherit;
                margin: auto;
            }
            
        
            
            [popover] {
                /* ссылаемся на якорь, к которому привязан поповер */
                position-anchor: --button-element;
                /* делаем поповер якорем */
                anchor-name: --popover-element;
            }
            /* хвостики */
            [popover]::before, [popover]::after {
                /* якоримся на тот же элемент, что и поповер */
                position-anchor: --button-element;
                content: '';
                position: fixed;
                background: inherit;
                margin: auto;
            }
            
        
            
            [popover] {
                /* ссылаемся на якорь, к которому привязан поповер */
                position-anchor: --button-element;
                /* делаем поповер якорем */
                anchor-name: --popover-element;
            }
            /* хвостики */
            [popover]::before, [popover]::after {
                /* якоримся на тот же элемент, что и поповер */
                position-anchor: --button-element;
                content: '';
                position: fixed;
                background: inherit;
                margin: auto;
            }
            
        
            
            [popover] {
                /* ссылаемся на якорь, к которому привязан поповер */
                position-anchor: --button-element;
                /* делаем поповер якорем */
                anchor-name: --popover-element;
            }
            /* хвостики */
            [popover]::before, [popover]::after {
                /* якоримся на тот же элемент, что и поповер */
                position-anchor: --button-element;
                content: '';
                position: fixed;
                background: inherit;
                margin: auto;
            }
            
        
            
            [popover] {
                /* ссылаемся на якорь, к которому привязан поповер */
                position-anchor: --button-element;
                /* делаем поповер якорем */
                anchor-name: --popover-element;
            }
            /* хвостики */
            [popover]::before, [popover]::after {
                /* якоримся на тот же элемент, что и поповер */
                position-anchor: --button-element;
                content: '';
                position: fixed;
                background: inherit;
                margin: auto;
            }
            
        
            
            /* задаем размеры хвостиков */    
            [popover]::before,
            [popover]::after {
                left: anchor(--button-element start);
                right: anchor(--button-element end);
                width: 10px;
                max-height: 10px;
            }
            
        
            
            /* для кейса, когда поповер под кнопкой */
            [popover]::before {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--button-element end);
                bottom: anchor(--popover-element start);
                transform: translateY(7px) rotate(45deg);
            }

            /* для кейса, когда поповер над кнопкой */
            [popover]::after {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--popover-element end);
                bottom: anchor(--button-element start);
                transform: translateY(-7px) rotate(45deg);
            }
            
        
            
            /* для кейса, когда поповер под кнопкой */
            [popover]::before {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--button-element end);
                bottom: anchor(--popover-element start);
                transform: translateY(7px) rotate(45deg);
            }

            /* для кейса, когда поповер над кнопкой */
            [popover]::after {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--popover-element end);
                bottom: anchor(--button-element start);
                transform: translateY(-7px) rotate(45deg);
            }
            
        
            
            /* для кейса, когда поповер под кнопкой */
            [popover]::before {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--button-element end);
                bottom: anchor(--popover-element start);
                transform: translateY(7px) rotate(45deg);
            }

            /* для кейса, когда поповер над кнопкой */
            [popover]::after {
                /* растягиваем хвостик между двумя якорями */
                top: anchor(--popover-element end);
                bottom: anchor(--button-element start);
                transform: translateY(-7px) rotate(45deg);
            }
            
        

А на 4 стороны?

Без единой строчки JavaScript'a
😍

Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Popover
auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y

Какие UI-паттерны закрывают dialog и popover?

<dialog>
popover

Как на практике использовать dialog и popover?

Компоненты на основе dialog и popover

Что дальше?

Open UI

Open UI

Invoker Commands

            
            <!-- Пример возможного синтаксиса -->
            <button 
                command="show-modal" 
                commandfor="my-dialog"
            >
                Открыть диалог
            </button>

            <dialog id="my-dialog">
                ...
            </dialog>
            
        
Эксплейнер для Invoker Commands
⚠️ Proposal

Interest Invokers

            
            <!-- Пример возможного синтаксиса -->
            <button interesttarget="my-popover">
                Показать поповер
            </button>

            <div id="my-popover" popover>
                Контент поповера
            </div>
            
        
Эксплейнер для Interest Invokers
⚠️ Proposal
            
                <!-- Пример возможного синтаксиса -->
                <button interesttarget="my-custom" interestaction="custom-action">
                    Покажу скрытый текст, если проявишь интерес
                </button>
                  
                <div id="my-custom">Скрытый текст</div>
                  
                <script>
                    const custom = document.getElementById("my-custom");
                    custom.addEventListener("interest", (e) => {
                      if (e.action !== "custom-action") return;
                      custom.classList.add('active')
                    });
                    custom.addEventListener("loseinterest", (e) => {
                      if (e.action !== "custom-action") return;
                      custom.classList.remove('active')
                    });
                </script>
            
        
Эксплейнер для Interest Invokers
⚠️ Proposal

Подведем итоги

Что разные подходы умеют по дефолту?

Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y
Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y

Что когда использовать?

Характеристика Кастом Dialog Popover
show() showModal() auto manual
Привязка к якорю
Внешний вид
Оверлей
Явное закрытие
Неявное закрытие
Закрытие на Escape
Focus trap
Top layer
Семантика / a11y

Инструкция из трёх шагов

Нужна поддержка
старых браузеров?

<div class="custom">

Нужна модальность?

<dialog>

Для всего остального есть...

popover

Репозиторий со слайдами

Открыт к диалогу!

Рома Ахмадуллин
Дром