Верстка с использованием CSS Flexbox

Намедни прочел новость о том что bootstrap 4 полностью перешел на флексбокс, поэтому я осознал что настал тот самый момент когда необходимо разобраться и понять что это за зверь такой.

Раньше в bootstrap 4 была Sass-переменная $enable-flex, с помощью которой можно было включить, либо выключить поддержку Flexbox. Также для карт, сетки, медиа-объектов, списков и компонентов навигации удалены non-flexbox варианты. В нем большое количество возможностей, которые облегчают жизнь верстальщику:

  • легкое вертикальное выравнивание содержимого внутри родительского элемента;
  • легкость в создании адаптивных столбцов;
  • создание столбцов одинаковой высоты;
  • проще перестроить контент для всех устройств и разрешений экранов с помощью media-запросов;
  • возможность прижатия содержимого к низу контейнера.

Шикарная демо-страница на которой можно сравнить сетку бутстрапа построенную по старым принципам и по новым, использующую флексбокс. Обратите внимание на вкладки Column Height и в особенности на Vertical Alignment. Со старой сеткой вертикального выравнивания невозможно достичь, а в новой нам помогает align-items, о котором я расскажу чуть ниже.

Старший умный был детина, средний был и так, и сяк, младший вовсе был дурак…
На самом деле эта фраза относится к поддержке Flexbox в браузерах Internet Explorer. Поддержку можно проверить на сайте caniuse. Начиная с Internet Explorer 11 нормально все поддерживается, с 10-ой версией есть известные проблемы, в том плане что там вроде бы и есть флексбокс, но он использует устаревший синтаксис версии 2012 года. Ну а Internet Explorer 9 и более старые версии вообще не имеют поддержки. Флекс модель поддерживается во всех современных браузерах.

По-простому Flexbox — это новый способ расположить блоки на странице. Есть несколько вариантов как можно управиться с элементами на странице. Начну с двух самых ужасных - можно заверстать все в таблицах и можно все расставить на свои места используя position: absolute. От этих методов уже давно все вменяемые люди отказались и перешли на блочную модель. Флекс-модель является следующим шагом в развитии. Аналогом display:block и display:inline-block является display:flex и display:inline-flex, первый ведет себя как блочный, а второй соответственно как строчный элемент и оба подчиняются правилам согласно флекс-модели.

Я специально указывал display, чтобы не было путаницы во свойством flex. Нужно различать свойства display: flex и flex: 1, первое указывает что это флексбокс модель, второе как правильно флекс элементу заполнять доступное пространство.

Итак, приступим к практике. Для того чтобы элементы контролировать с помощью флексбокс модели в первую очередь необходимо эту модель указать элементу-родителю. Если у элемента указано абсолютное позиционирование, то флексбокс не будет работать, так как он находится вне потока.

Flex-direction - это свойство указывает направление, в котором мы хотим выложить наши flexbox элементы. Оно принимает в качестве значений следующие варианты: row (значение по умолчанию), row-reverse, column и column-reverse.

Row - элементы располагаются в ряд, направление по умолчанию такое же как и у текста то есть слева направо. Однако если указать dir как rtl, то направление оси идёт справа налево. Атрибут dir указывает направление текста. Если указано ltr, то текст отображается как обычно — слева направо, если же rtl, то текст инвертируется и отображается справа налево. Этот атрибут используется например для арабских и еврейских символов.

Значение row-reverse противоположно предыдущему и также зависит от атрибута dir. Значение column для flex-direction указывает что флекс-элементы располагаются вертикально и очередность их направлена сверху вниз. Ну а противоположное значение это - column-reverse.

Пример со всеми возможными вариантами вышеописанных свойств. https://jsfiddle.net/krontill/5vpdduu7/1/

Сделать одну колонку шире другой в два раза поможет указание свойства flex: 1 и для широкой колонки flex: 2. В этом свойстве можно скомпоновать сразу три, например flex: 0 0 auto. Flex-basis используется для указания начального размера элемента относительно родителя, по умолчанию auto, а можно указать в единицах измерения, например процент, px, mm, pt. Свойство flex-grow задает пропорции каждого флекс элемента, именно это свойство срабатывает когда мы в начале абзаца делали одну колонку шире другой в два раза. flex-shrink: <число> - это коэффициент сжатия флекс элементов, которое указывает, насколько элемент будет уменьшаться по отношению к другим флексам, чтобы разместить все элементы в одну строку.

Сортировка флекс элементов осуществляется свойством order, которое определяет очередность флексов. Располагаются от меньшего к большему, а если значения одинаковые, то исходя из расположения в коде.

Свойство align-items выравнивает элементы по поперечной оси внутри родителя. Flex-start прижимает к верху, flex-end к низу, center располагает элементы по центру, baseline по базовой линии, а stretch растягивает на всю высоту. Аналогично выравнивает align-self, только для элементов, а не родителя.

Выравнивание строк внутри флекс-контейнера задает align-content по поперечной оси при наличии свободного пространства. При flex-start строки располагаются в начале поперечной оси, при center - в центре, при flex-end - в конце, если указано space-between, то строки равномерно распределяются в контейнере и расстояние между ними одинаково. При space-around строки равномерно распределяются таким образом, чтобы пространство между двумя соседними строками было одинаковым. Пустое пространство перед первой строкой и после последней строки равно половине пространства между двумя соседними строками. При stretch строки растягиваются.

Свойство justify-content делает то же самое что и align-content, только для главной оси.

Флексы можно заставить располагаться в одну строчку, а можно разрешить в несколько строк, если такое разрешение есть, то можно контролировать направление строки. Это делает flex-wrap: nowrap - в одну строку, wrap и wrap-reverse - несколько строк, но с разным направлением, которое зависит от flex-direction, описанное выше.

Можно объединять некоторые свойства.
//flex-direction: row; + flex-wrap: nowrap;
flew-flow: row nowrap;

//flex-direction: column; + flex-wrap: wrap;
flex-flow: column wrap;

flexbox

Часто для флексов пишут не вертикальная и горизонтальная а, основная и поперечная оси. Это из-за того, что оси могут менять порядок и, соответственно, вертикальная становится горизонтальной и обратно.

Для дальнейшего изучения рекомендую несколько примеров из реальной верстки. Шикарный пример http://codepen.io/anon/pen/LZVbNm по такой же замечательной статье https://habrahabr.ru/post/314034/, которая рассказывает о том как сверстать новостной сайт с использованием css flexbox. Второй отличный пример это подробная статья по вёрстке интерфейсов с использованием css flexbox - Going all-in on Flexbox.

Happy coding ;)