Как стать автором
Обновить

Комментарии 15

Было бы неплохо добавить ссылку на какой-нибудь jsfiddle и гифку с анимацией, как это работает.

Добрый вечер, большое cпасибо за критику, до 10 июня обновлю статью и добавлю ссылку на песочницу кода + гифку.

P.S К слову, такой долгий срок обусловлен тем, что на момент написания кода не думал, что буду выкладывать его в песочницу. Но сейчас, немного почищу код, добавлю комментарии, чтобы читать его было проще, а потом выложу его в песочницу.

Единственный вариант, в котором анимация через 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 стиль, и элемент плавно сворачивается.

Кажется, это самое простое решение.

Тут возникает другая проблема, что высота контента может поменяться (например вследствие изменении размера окна), и тогда контент вылезет за зафиксированную скриптом высоту. Со скриптами можно уже и нормально реализовать. Навесив на transitionend - height: auto.

Метод неплохой, но ещё есть потенциальная проблема, если высота контента внутри аккордеона превысит высоту, которая у вас указана в 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) страница все равно будет вынуждена перерисоваться, чтобы сместить блоки под формой, либо показать фон за ней, если форма не влияет на окружение и позиционировано абсолютно.

Transform: translate без position absolute
Transform: translate без position absolute

Недавно столкнулся с этой проблемой и пришёл к точно такому же решению)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории