Комментарии 15
Было бы неплохо добавить ссылку на какой-нибудь jsfiddle и гифку с анимацией, как это работает.
Добрый вечер, большое cпасибо за критику, до 10 июня обновлю статью и добавлю ссылку на песочницу кода + гифку.
P.S К слову, такой долгий срок обусловлен тем, что на момент написания кода не думал, что буду выкладывать его в песочницу. Но сейчас, немного почищу код, добавлю комментарии, чтобы читать его было проще, а потом выложу его в песочницу.
Статью обновил, добавил ссылку на codepen и гифки
Единственный вариант, в котором анимация через max-height будет смотреться корректно, это когда известен размер анимируемого блока. А вот так анимировать, я бы не советовал. Будет выглядеть неровно/некрасиво/убого, особенно если вы применяете не линейную функцию плавности.
Альтернатива - это анимация колонки на гридах. Здесь, кажется, уже где-то проскакивало. К сожалению, из-за бага поддержка этого метода оставляет желать лучшего.
Да, соглашусь с тем, что анимация через max-height имеет свои недостатки, и если я найду более оптимальное решение, то поделюсь им. Однако, кроме известного размера блока, дёрганость можно решить микроанимациями (0.3 и 0.2 s), что не дает ее увидеть, а ощущение плавности для пользователя всё же создастся.
Также, поблагодарю за предложение решения через колонки гридов, т.к никогда об этом не слышал, и даже несмотря на какой-то баг, будет интересно это изучить.
Спешу вас порадовать. Через max-height, даже без заранее известного размера блока, можно добиться плавности. Добавьте cubic-bezier
.text {
overflow: hidden;
max-height: 0;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
&.full {
max-height: 1000px;
transition: max-height 1s ease-in-out;
}
Да, у этого метода есть недостаток с различным временем анимации.
Я тоже в свое время кучу экспериментов перепробовал, но всетаки остановился на анимации height. Т.е. все как и в статье overflow:hidden, height:0 и transition на height.
А потом просто по клику в скрипте:
elem.style.height = `${elem.scrollHeight}px`;
что добавляет inline стиль height с актуальной высотой элемента и за счет css перехода, он анимируется. И при закрытии соответственно.
elem.style.height="";
это убирает inline стиль, и элемент плавно сворачивается.
Кажется, это самое простое решение.
Метод неплохой, но ещё есть потенциальная проблема, если высота контента внутри аккордеона превысит высоту, которая у вас указана в max-height и содержимое начнет "вываливаться" из него
Именно поэтому в моем случае высота контента около 550px, а высота max-height 3000px. Да такая разница в высоте создает небольшую задержку, но добавляет надежности, ведь я не думаю, что заказчик увеличит блок с формой в 4 с половиной раза
P.S Благодаря вашему комментарию, добавил информацию об указании высоты с запасом в статью, чтобы любой, без чтения комментариев мог узнать про это. Спасибо
Интересная тема. Вопрос следующий: анимация hight на странице перерисовывает полностью всю страницу (F12 > Console > Ecs > Rendering > Paint Flashing). Как реализовать аккордеон с плавной анимацией без перерисовки макета? (может быть использовать opacity, transform ...)
Если аккордеон меняется в размерах после анимации (как в случае с max-height), то никак, т.к его уменьшение ведет за собой и смещение контента под ним наверх, либо появление контента скрывающегося под ним, если например форма позиционирована абсолютно и не влияет на окружение, когда она сворачивается.
Если аккордеон не меняется в размерах (как в случае с opacity, transform), страница не перерисовывается и под ним остается пустое место, что не выглядит красиво, а если это пустое место убрать (например с помощью position: absolute ; top : -100%; и для родителя overflow:hidden) страница все равно будет вынуждена перерисоваться, чтобы сместить блоки под формой, либо показать фон за ней, если форма не влияет на окружение и позиционировано абсолютно.
Недавно столкнулся с этой проблемой и пришёл к точно такому же решению)
Анимация аккордеона и свойства height (max-height) в чистом CSS