Flexbox: уже пора!

Написана уже куча статей про Flexbox, описаны все параметры, но до сих пор находятся люди, которые даже не слышали об этой технологии. И это очень плохо. Но ещё хуже, что некоторые люди не используют эту чудесную технику из-за, якобы, плохой поддержки браузеров. Что ж, давайте разберем что же такое flexbox, какие браузеры его поддерживают и как, где, а главное — стоит ли, его использовать.

Пара слов о поддержке Flexbox

Нынешняя спецификация flexbox не первая. В 2012 году… Впрочем, кого это волнует?
Новую спецификацию, по данным caniuse, поддерживает уже 79% браузеров. Добавим к этому поддержу с префиксами — и получим цифру 83%. Если ж учесть и частичную поддержку в Android 4.1-4.3 — то и вовсе доберемся до фантастических 94.5%! Флекс поддерживает даже последняя OperaMini!

Кто не поддерживает флексбокс?

  • Internet Explorer младше 11 версии (IE10 частично поддерживает спецификацию 2012)
  • Люди считающие, что «С каждой версией iOS моросит всё больше» и сидящие на версии ниже 6.1
  • Пользователи UC Browser, который почему-то до сих пор только частично поддерживает, хотя и использует в качестве движка webkit
  • Пользователи Android ниже версии 4.4 (версии ниже, всё также, только частично поддерживает флекс), которые используют РОДНОЙ браузере.

Остальные, в принципе, даже не нуждаются в упоминании, так как их количество ничтожно мало и с каждым днем всё больше близится к нулю.
На данный момент на github разрабатывается полифил для поддержки флекса, но разработка идёт очень медленно, автор просит помощи и скорее браузеры, не поддерживающие эту замечательную фишку, канут в Лету, чем автор завершит своё творение.

Flexbox: инструкция по применению

Для начала: что стоит знать?

В первую очередь, нужно указать родителю display: flex или display: inline-flex. Различие между ними такое же, как и между block и inline-block или между table и inline-table, так что останавливаться на этом не будем.

Существуют параметры для родительского и дочерних элементов. Я разделю их, чтобы было понятнее:

Свойства родительского контейнера:

Свойство flex-direction (направление оси)

Определяет то, в каком направлении будут располагаться дочерние элементы: по горизонтали или по вертикали.

Значения:

  • row (по умолчанию) — привычно, слева на право
  • column — столбиком
  • row-reverse — по-арабски, справа налево
  • column-reverse — по-идиотски, снизу вверх

Свойство justify-content (выравнивание по главной оси)

Определяет выравнивание дочерних элементов по главной оси. Стоит обратить внимание, что это свойство не всегда отвечает за выравнивание элементов по горизонтали. Оно отвечает именно за главную ось. По умолчанию главная ось является горизонтальной, но если вы задали свойство flex-direction: row, то главная ось станет вертикальной.

Значения:

  • flex-start (по умолчанию) — начало родительского блока
  • flex-end — конец родительского блока
  • center — центр родительского блока

И вот тут начинается самое интересное

  • space-between — первый дочерний элемент — в начале, последний — в конце. Остальные расположены так, чтобы между ними было одинаковое расстояние
  • space-around — все тоже самое, но перед первым и после последнего элементов также есть отступы, которые равны отступам между элементами

Свойство align-items (выравнивание по поперечной оси)

Дождались! Свойство, которое позволяет забыть о геморрое с vertical-align: center и top: 50%/transform: translateY(-50%).
Как и в предыдущем свойстве, не стоит забывать, что оно отвечает за выравнивание по поперечной оси, которая, в зависимости от значения flex-direction, может идти по вертикали или по горизонтали.

Уже знакомые нам значения:

  • flex-start — прижатие к началу
  • flex-end — прижатие к концу
  • center — по центру

А также парочка других, на замену space-between и space-around:

  • baseline — выравнивание по базовой линии
  • stretch (по умолчанию) — растягивает на 100%

Свойство flex-wrap (одно- или многоколоночность)

По умолчанию flex сжимает все блоки так, чтобы они уместились в одном ряду. При желании, это можно изменить.

Значения:

  • nowrap (по умолчанию) — одна строка/колонка (в зависимости от значения flex-direction). Все дочерние блоки сжимаются.
  • wrap — многоколоночность. То что не влезло переносится на новую строку или в новую колонку
  • wrap-reverse — тоже, только наоборот: элементы идут в обратном порядке

Свойство align-content (небольшое дежавю)

Данное свойство выравнивает строки/колонки, которые образовались в результате использования flex-wrap: wrap/wrap-reverse.

Значения:

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • stretch (по умолчанию)

Описывать их не буду, они распределяют элементы так же, как и одноименные значения в justify-content/align-items.

Свойства дочерних элементов:

flex-basis (размер элемента)

Значение по умолчанию: auto.

По-моему личному мнению, наименее востребованное свойство. Указывает размер элемента по главной оси (в любых единицах измерения).

flex-grow (расширяемость элемента)

Значение по умолчанию: 0 (не забирает себе ни одну часть свободного места).

Указывает сколько долей свободного места элемент может забрать себе.

Пример 1:
Родитель — ширина 1000px,
Элемент-1 — flex-grow: 1,
Элемент-2 — flex-grow: 3.
Стало быть элемент-1 будет иметь длину 1000/(1+3)*1=250px, а элемент-2 — оставшиеся 750px.

Пример 2:
Условия те же, но у обоих элементов указана ширина — 100px.
В таком случае элемент-1 будет иметь ширину (1000-(100+100))/(1+3)*1+100=300px, а элемент-2 — 700px.
Что означают эти вычисления? Для начала мы узнали количество оставшегося места (1000-(100+100)=800), затем разделили на общее количество долей(800/(3+1)=200), и наконец отдали первому элементу его долю + 100px, которые были у него изначально (200*1+100=300).

flex-shrink (сжимаемость элемента)

Значение по умолчанию: 1 (уменьшается одинаково с другими элементами).

Аналогичное свойство, но работающее в обратном направлении. Указывает пропорцию уменьшения блока, по отношению у другим элементам.

Пример 1:
Родитель — 1000px,
Элемент-1 — flex-shirk: 0,
Элемент-2 — flex-shrink: 1,
У обоих элементов указана ширина 650px.
Что произойдет? Первому элементу указано свойство flex-shrink: 0 т.е. ему запрещено уменьшаться. Значит это придется сделать второму элементу. В итоге ширина элемента-1 будет равна 650px, а элемента-2 — 350px.

Пример 2:
Элемент-1 — flex-shrink: 1,
Элемент-2 — flex-shrink: 2,
Остальные условия те же.
Как вы, возможно, уже догадались, ширина первого блока составит 550px, а второго — 450px. Но давайте всё таки проследим за тем, что произошло:
Для начала определяется количество недостающего места (650+650-1000=300), затем вычисляется размер одной доли flex-shrink (300/(1+2)=100) и, наконец, из  каждого элемента вычитается указанная в его стилях доля (650-100*1=550px и 650-100*2=450px).

align-self (выравнивание отдельного элемента по поперечной оси)

Указывает расположение по поперечной оси отдельно взятого элемента. Можно контейнеру указать align-items: flex-start и несколько элементов отправить, например в конец, приписав им align-self: flex-end.

Значения те же, что и у align-items:

  • flex-start
  • flex-end
  • center
  • baseline
  • stretch

order (порядок элемента)

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

Ну вот и всё! Также объединять некоторые свойства и записывать их в сокращенном виде (например, flex: 1 2 200px), но, пожалуй, не будем об этом.

Что бы хотелось сказать в конце:
Flexbox поистине удивительный инструмент. Попробовав его один раз, удивляешься, как до сих пор работал без него. С помощью него можно очень легко менять поток элементов сайта. Это очень удобный инструмент для адаптивной верстки.
Но не стоит пихать его везде, заменяя им всё что можно и нельзя. Как и любой другой инструмент, использовать его стоит с умом.

comments powered by HyperComments

Автор

webbeaver

webbeaver

Верстаю, читаю, учусь