Как анимировать открытие диалога или поповера
Короткий ответ
Опишите открытое состояние, начальное через @starting-style и разрешите анимировать display:
<style>
dialog { opacity: 0; translate: 0 20px;
transition: opacity 0.3s, translate 0.3s, display 0.3s allow-discrete, overlay 0.3s allow-discrete; }
dialog[open] { opacity: 1; translate: 0 0; }
@starting-style { dialog[open] { opacity: 0; translate: 0 20px; } }
</style>
<button onclick="hello.showModal()">Open</button>
<dialog id="hello">
<p>Hello! This window fades in.</p>
<form method="dialog"><button>Close</button></form>
</dialog>Как это работает:
@starting-styleзадаёт стиль, с которого элемент начинает переход в момент появления. Без него браузеру не от чего анимировать: элемент былdisplay: none.allow-discreteуdisplayоткладывает скрытие до конца перехода, поэтому закрытие тоже плавное.overlayдержит диалог в верхнем слое, пока идёт анимация закрытия.
Поповер
Для popover всё так же, только открытое состояние — псевдокласс :popover-open:
<style>
[popover] { opacity: 0; scale: 0.9;
transition: opacity 0.25s, scale 0.25s, display 0.25s allow-discrete, overlay 0.25s allow-discrete; }
[popover]:popover-open { opacity: 1; scale: 1; }
@starting-style { [popover]:popover-open { opacity: 0; scale: 0.9; } }
</style>
<button popovertarget="menu">Menu</button>
<div id="menu" popover>Settings · Profile · Log out</div>Затемнение фона
::backdrop анимируется так же: задайте ему прозрачный фон по умолчанию, полупрозрачный для dialog[open]::backdrop, тот же transition и начальное состояние в @starting-style.
Частая ошибка
Ставить @starting-style раньше правила для открытого состояния с той же специфичностью. Блок @starting-style не повышает специфичность, и правило ниже его перебивает — анимация входа пропадает. Пишите @starting-style после основных стилей, как в примерах. В браузерах без поддержки окно просто откроется без анимации.
Функции из этого ответа
- @starting-style — Задаёт стили, с которых элемент начинает при первом появлении, чтобы `transition` анимировал его появление.
- transition-behavior — Разрешает переходы дискретных свойств вроде `display` и `overlay`, чтобы элемент успел плавно исчезнуть, прежде чем пропасть.
- <dialog> — Диалоговое окно; модальное открывается методом `showModal()` и блокирует остальную страницу.
- popover — Превращает элемент во всплывающий слой поверх страницы — без JavaScript.
- transition — Плавно анимирует изменение свойства от старого значения к новому.