[Из песочницы] Анимирование Flexbox с помощью CSS Transition

Все уже знают про Flexbox. Кто-то испытывает его на продакшене, кто-то только изучает, а кто-то недоумевает, чем он лучше таблиц. Пока вы занимаетесь этим, поделюсь с вами приятной новостью: flexible контейнеры неплохо анимируются с помощью CSS transition.Расскажу, как это использовать и что с этой радостью можно делать.Под анимацией я имею в виду изменение размеров контейнеров. Казалось бы, ничего удивительного, ведь есть transition: width 0.3s ease. Однако анимация flexible-элементов подразумевает, что размеры нескольких контейнеров изменяются одновременно. Это дает просто безграничные просторы для анимирования изменения размеров лэйаута. Например, сейчас очень популярно меню, которое схлопывается, оставляя видимыми только иконки.

d80e715461574066a556a4290582b269.pngСмотреть демо на Codepen.ioЧтобы сделать такое меню с привычными контейнерами, надо синхронно анимировать изменение ширины двух контейнеров. С другой стороны, если отбросить условности необходимость поддерживать старые браузеры, то можно сделать такую же разметку с помощью Flexbox. Тогда можно использовать следующий код для анимации:

.menu { flex: 0.0001 1 180 px; transition: flex 0.3s ease; } .collapsed .menu { flex: 0.0001 1 48 px; } Код для анимирования изменения размеров умещается в одну строку. В качестве CSS-свойства, которое будет анимировано, передаем «flex».Немного странно здесь выглядит значение flex-grow. Это фактор расширяемости, который указывает, насколько хорошо будет растягиваться контейнер относительно других контейнеров, если родительский элемент имеет свободное место после расчета базовых размеров вложенных элементов. Чем меньше это значение относительно других, тем меньше контейнер будет расширяться. Если использовать значение 0, то ширина (или высота) элемента будет фиксированной. Если же ширина будет фиксированной, то возникает проблема с анимацией: более старая версия Google Chrome напрочь отказалась анимировать изменение размеров при значении flex-grow равным нулю. Есть вероятность, что в некоторых версиях браузеров такая проблема все еще существует.Фотогалерея Давайте пойдем немного дальше: возьмем 5 фотографий, расположим их в одной строке.b12e361b50ec4ecf8664e114f4afacd7.png При наведении курсора будем показывать выбранную фотографию в увеличенном формате9c75969cf5754b0286ff7827c97202b4.png Для расположения фотографий будем использовать Flexbox, а изображения вставим через background-image:

.items-row { display: flex; flex-flow: row nowrap; } .item { flex: 1 1 20%; } .img1 { background-image: url ('http://lorempixel.com/400/400/?1'); background-repeat: no-repeat; } Все элементы flex-контейнера занимают изначально по 20% от ширины и равноценно расширяются/сжимаются. Чтобы активный элемент увеличивался при наведении курсора, добавим правило, которое устанавливает фиксированную ширину 400 пикселей и уменьшает расширяемость/сжимаемость элемента почти до нуля:

.item: hover { flex: 0.000000001 0.00000001 400 px; } Теперь при наведении курсора все неактивные элементы сожмутся, потому что имеют значение flow-shrink: 1, а активный элемент останется шириной 400 пикселей, потому что он почти несжимаем.Последний штрих — добавление анимации:

.item { transition: flex 0.4s ease; } Смотреть демо на Codepen.ioЕсли пойти еще дальше, то можно сделать несколько рядов фотографий и при наведении курсора увеличивать не только ширину, но и высоту. Для этого надо повторить то же самое, но с flex-flow: column nowrap;.

624a81fd69b2494cba7d888677d75ce3.png А вот что будет, если навести курсор на фотографию933dbaa721664ac08e7e049137e7a8f2.png Смотреть демо на Codepen.ioПроизводительность Редкое обсуждение анимации обходится без разговоров о FPS. Поэтому на моем неторопливом компе я измерял FPS для последней демки. И вот что я получил: 31f5b236f59b4e939853c5ce074ada26.png Да, выглядит вполне неплохо. Да и вообще я как-то замерял скорость отрисовки интерфейса сделанного с помощью Flexbox и аналогичного, сделанного на float’ах. Интерфейсы включали в себя по 1500 элементов. Разница в рендеринге составляла около 10 мс на десктопе и около 15–20 мс на мобильном устройстве. Поэтому, если производительность для вас решающий фактор, то вы проиграете немного.

Поддержка браузерами К сожалению, это не кроссбраузерная радость. Поскольку Flexbox работает в IE10+, соответственно, и его анимация будет работать не менее, чем с 10-й версии. С другой стороны, для приведенного примера нетрудно сделать фоллбэк, который будет более-менее прилично отображать фотографии в маленьком размере и увеличивать их с помощью какого-нибудь расширения.Выводы Анимировать изменение размеров flexbox-элементов легко: transition: flex 0.4s ease;; Отличные от нуля (0.000001) значения flex-grow и flex-shrink могут все исправить, если анимация не работает; По производительности анимация Flexbox контейнеров почти не уступает анимации элементов div с float; Это очень свежее решение, поэтому использовать его стоит с осторожностью, а тестировать как можно больше. Полезные материалы

© Habrahabr.ru