TGViewer
Логово верстальщика Логово верстальщика @webdevlair · 7.97K subscribers
Post #4548 357
⁣Есть два мощных CSS-механизма, которые позволяют анимировать появление и исчезновение попапов, диалогов и вообще любых элементов с display: none без единой строчки JS. Речь про @starting-style и transition-behavior: allow-discrete.

---

## Проблема
Раньше нельзя было плавно показать попап, который скрыт через display: none (стандарт для popover/dialog в закрытом состоянии). Браузер не мог найти стартовое состояние для перехода. Результат — либо мгновенное появление, либо костыли с JS и реквайрами.

## Решение

**Шаг 1. display и overlay участвуют в transition**

Свойство display — дискретное. Чтобы переход не сработал мгновенно, нужно разрешить дискретные значения анимироваться:

transition-behavior: allow-discrete;


Если указать это в transition для display, то браузер «перекидывает» значение с none на block в **начале** анимации появления и в **конце** анимации исчезновения. Элемент для закрывающегося попапа остаётся видимым до конца анимации, а потом получает display: none.

Для попапов важно ещё и overlay — отключает верхний слой (top layer) только после завершения анимации.

**Шаг 2. @starting-style — стили «до старта»**

Когда браузер переключает display с none, у элемента нет предыдущего состояния, от которого можно анимировать. @starting-style задаёт стартовые стили:

.popover {
opacity: 0;
transform: translateY(-10px);
transition:
opacity 0.3s ease,
transform 0.3s ease,
display 0.3s allow-discrete,
overlay 0.3s allow-discrete;
}

.popover:popover-open {
opacity: 1;
transform: translateY(0);
}

@starting-style {
.popover:popover-open {
opacity: 0;
transform: translateY(-10px);
}
}


## Как это работает

- При открытии: @starting-style мгновенно применяет opacity: 0, затем срабатывает переход к opacity: 1.
- При закрытии: обычные стили возвращают попап к opacity: 0, а display: none и уход из top layer (overlay) применяются только в конце transition.

## Важные нюансы

1. Без allow-discrete display переключится мгновенно, анимация исчезновения не будет.
2. overlay нужно указывать именно для элементов в top layer (popover, dialog). Обычные выпадашки могут обойтись без него.
3. Поддержка: все современные браузеры, включая Safari 17.5+ и Chrome 117+. Работает и для <dialog>, и для [popover].

## Минимальный пример

<button popovertarget="tip">Показать</button>
<div popover id="tip">Подсказка</div>


#tip {
opacity: 0;
transform: scale(0.95);
transition:
opacity 0.2s ease,
transform 0.2s ease,
display 0.2s allow-discrete,
overlay 0.2s allow-discrete;
}

#tip:popover-open {
opacity: 1;
transform: scale(1);
}

@starting-style {
#tip:popover-open {
opacity: 0;
transform: scale(0.95);
}
}


Теперь никакого JS для анимации попапов — только чистый CSS. Удобно, когда нужно скрыть логику анимации из бандла и убрать хрупкие кодушки с анимациями через классы.
More from @webdevlair
  1. Sep 25, 2026⁣CSS :nth-child(An+B of S) - сложные выборки без JS Раньше «каждый второй среди подходящих…
  2. Sep 25, 2026Post #4631
  3. Sep 25, 2026Кто-то из Anthropic скинул годный трюк для Opus 5.5. Суть простая: в Claude Code дёрни /cl…
  4. Sep 25, 2026Post #4629
  5. Sep 24, 2026Claude Opus 5.5 не где-то там — она уже здесь, и в большинстве бенчмарков она укладывает н…
  6. Sep 24, 2026Post #4626
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →