Плавное изменение высоты блока на CSS
Рассмотрим способ решения проблемы сворачивания и разворачивания блока неизвестной высоты на чистом CSS. Это распространённая задача, которая часто вызывает трудности в реализации, когда значение свойства «height» не задано явно, а находится в состоянии «auto».
Для начала посмотрите как работает решение на практике:
Принцип работы
Обычная реализация подразумевает знание начальной и конечной высоты блока. Чтобы обойти это ограничение, будем использовать свойство «max-height». Для свёрнутого значения оно будет нулевым, а для открытого — максимально большим. В нашем случае точно хватит 1000 пикселей.
Стиль блока в раскрытом состоянии:
.expansion-body { overflow: hidden; max-height: 1000px; transition: max-height 0.3s cubic-bezier(1, 0, 1, 0); }
Свёрнутое состояние будет происходить за счёт добавления класса «expansion-hide».
.expansion-hide { max-height: 0; transition: max-height 0.3s cubic-bezier(0, 1, 0, 1); }
- В развёрнутом виде у «DIV» будет класс «expansion-body».
- В свёрнутом — «expansion-body expansion-hide».
Плавное сворачивание и разворачивание достигается с помощью нелинейной трансформации максимальной высоты. Значение от 1000 до 0 меняется сначала очень быстро, а потом резко замедляется. Это сглаживает анимацию, если высота блока намного меньше 1000 пикселей. При обычной линейной трансформации при сворачивании была бы задержка.
Описанный способ легко адаптируется для плавного изменения ширины путём применения свойства «max-width».
Добавление класса и возможные проблемы
Для добавления и удаления класса «expansion-hide» в примере использовался чистый JS. Он не влияет на сам процесс анимации. В обработчике «onclick» всего одна строка кода.
document.getElementById('expansion-body').classList.toggle('expansion-hide')
Сама html-разметка также проста:
<div id="expansion-body" class="expansion-body"> DIV </div>
Небольшое предупреждение — не добавляйте к блоку отступы «padding», иначе он не будет до конца закрываться. Если они нужны, то создайте внутри ещё один «div» и добавляйте произвольные стили к нему.
PS Чтобы поблагодарить за решение напишите любой комментарий.