Раньше плавное появление скрытого элемента требовало костылей: setTimeout, requestAnimationFrame, манипуляции с visibility и высотой. В production-интерфейсах — модалки, дропдауны, тултипы — этот паттерн выглядел как хрупкая конструкция, ломающаяся при малейшей асинхронной загрузке. Типичная ошибка: пытаться анимировать display напрямую, но CSS игнорирует переходы для дискретных свойств.
Как это работает
@starting-style задаёт начальные стили для только что добавленного элемента. А transition-behavior: allow-discrete разрешает анимировать дискретные свойства, например display. В сочетании с обычным transition браузер сам вычисляет промежуточные состояния. Пример для модалки:.modal {
display: none;
opacity: 0;
transition: opacity 0.5s, display 0.5s allow-discrete;
}
.modal.show {
display: block;
opacity: 1;
}
@starting-style {
.modal.show {
opacity: 0;
}
}Добавляем класс
show — элемент плавно появляется. Без JS-триггеров и магии. Браузер сам оптимизирует анимацию, не блокируя main thread.Production-ориентированный пример
В дизайн-системах для адаптивных лендингов используйте этот подход для аккордеонов или показа дополнительных опций. Но помните: обратный переход при скрытии тоже анимируется, если прописать
@starting-style для состояния без класса. Проверяйте поддержку: Chrome 117+, Edge, Opera. Firefox и Safari пока не имплементировали.Когда не стоит полагаться
Типичная ошибка: пытаться анимировать
display в сочетании с большими макетами, где браузер может отказаться от рефлоу. Для сложных виджетов (например, с изменением grid-размеров) всё ещё надёжнее использовать requestAnimationFrame или content-visibility. Также помните, что @starting-style требует явного класса или состояния — для псевдоклассов вроде :hover это не сработает.Практический совет
Для компонентов, которые часто появляются и исчезают (тултипы, выпадающие списки), проверьте кросс-браузерность: добавьте fallback через JS с помощью
Web Animations API на случай отсутствия поддержки. Это сохранит UX без потери производительности.Вывод:
@starting-style с allow-discrete — лаконичный паттерн для простых сценариев, но для production-уровня требуются fallback и тестирование на Firefox и Safari.