Почему toast не отображается поверх dialog и как это исправить

    Разработчики часто сталкиваются с ситуацией, когда всплывающие уведомления (toast) перестают быть видны после внедрения модальных окон через элемент <dialog>. Это связано с тем, что <dialog> помещается в top-layer - специальный слой браузера, который находится выше всех обычных элементов, включая ваши кастомные плашки.

    Причина: top-layer и z-index

    Элемент <dialog> с атрибутом open или после вызова .showModal() автоматически попадает в top-layer. Этот слой не подчиняется правилам z-index и всегда отрисовывается поверх остального контента. Даже если задать toast огромный z-index: 99999, он останется под диалогом, потому что top-layer физически выше в стеке отрисовки.

    Рабочие решения

    1. Помещение toast внутрь dialog (с управлением жизненным циклом)

    Этот вариант предложил ИИ. Суть: при открытии диалога вы переносите узел toast внутрь <dialog> через appendChild, а при закрытии - возвращаете обратно в родительский контейнер. Недостаток: нужно следить за событиями открытия/закрытия и корректно восстанавливать позиционирование.

    // Пример на JavaScript
    const dialog = document.querySelector('dialog');
    const toast = document.querySelector('.toast');
    
    dialog.addEventListener('close', () => {
      document.body.appendChild(toast);
    });
    
    dialog.addEventListener('open', () => {
      dialog.appendChild(toast);
    });
    

    2. Отказ от dialog в пользу кастомного модального окна

    Если вы не привязаны к семантике <dialog>, проще всего реализовать модальное окно на <div> с управлением z-index. В этом случае toast будет просто иметь больший z-index, чем модалка, и проблема исчезнет. Недостаток: потеря нативной доступности (ARIA-атрибуты и управление фокусом придётся добавлять вручную).

    3. Использование Popover API (если допустим современный браузер)

    Popover API (свойство popover) также работает через top-layer, но поддерживается с 2024-2025 года. Для вас этот вариант не подходит, так как моральная отсечка - 2022 год.

    Рекомендация

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

    • Атрибут role="dialog" и aria-modal="true"
    • Обработку фокуса (ловушка фокуса внутри модалки)
    • Закрытие по клавише Escape

    Таким образом, вы получите полный контроль над z-index и сможете легко управлять видимостью toast-уведомлений.

    Часто задаваемые вопросы