Укр Рус
Що таке Flexbox? Опис усіх CSS властивостей, основні принципи, переваги та недоліки

Що таке Flexbox? Опис усіх CSS властивостей, основні принципи, переваги та недоліки

  • 16 березня
  • читати 15 хв

Flexbox можна назвати вдалою спробою вирішення величезного спектра проблем при побудові лейаутів в CSS. Але перш ніж перейти до його опису, давайте з'ясуємо, що не так зі способами верстки, якими ми користуємося зараз?

Будь-який верстальник знає кілька шляхів вирівняти щось по вертикалі або зробити 3-х колонковий макет із гумовою середньою колонкою. Але давайте визнаємо, що всі ці способи досить дивні, схожі на хак, підходять не завжди, складні для сприйняття і не працюють при недотриманні певних магічних умов, які склалися історично.

Сталося так тому, що HTML та CSS розвивалися еволюційно. На початку веб-сторінки були схожі на однопотокові текстові документи, згодом розбиття сторінки на блоки робили таблицями, потім стало модним верстати float-ами, а після офіційної смерті IE6 додалися ще й прийоми з inline-block. У результаті ми отримали у спадок гримучу суміш усіх цих прийомів, використовувану для побудови лейаутів 99,9% всіх існуючих веб-сторінок.

Специфікація CSS Flexible Box Layout Module (у народі — Flexbox) покликана кардинально змінити ситуацію на краще при вирішенні величезної кількості завдань. Flexbox дозволяє контролювати розмір, порядок та вирівнювання елементів по кількох осях, розподіл вільного місця між елементами та багато іншого.

Основні переваги Flexbox

  1. Всі блоки дуже легко робляться «гумовими», що вже випливає з назви «flex». Елементи можуть стискатися та розтягуватися за заданими правилами, займаючи потрібний простір.
  2. Вирівнювання по вертикалі та горизонталі, базової лінії тексту працює шикарно.
  3. Розташування елементів HTML не має вирішального значення. Його можна змінити в CSS. Це особливо важливо для деяких аспектів Responsive верстки.
  4. Елементи можуть автоматично вишиковуватися в кілька рядків/стовпців, займаючи все надане місце.
  5. Безліч мов у світі використовують написання праворуч ліворуч rtl (right-to-left), на відміну від звичного нам ltr (left-to-right). Flexbox пристосований для цього. У ньому є поняття початку та кінця, а не права та лева. Тобто. у браузерах з локаллю rtl всі елементи будуть автоматично розміщені у реверсному порядку.
  6. Синтаксис CSS правил дуже простий та освоюється досить швидко.

Поддержка браузерами

Поддержка браузерами пока неполная (2014). Виноват в этом в основном Internet Explorer, который поддерживает спецификацию 2011 года только начиная с 10 версии.

Не смотря на это, обратите внимание на обширность поддержки всеми остальными мобильными и десктопными браузерами! Тут все прекрасно. Если вам нужна мобильная версия сайта или web-based приложение, то его уже можно (а, возможно, и нужно) делать, используя все преимущества Flexbox!

Начинаем погружение

Flexbox определяет набор CSS свойств для контейнера (flex-контейнер) и его дочерних элементов (flex-блоков).

Первое, что нужно сделать — это указать контейнеру display:flex или display:inline-flex.

<div class="my-flex-container">
  <div class="my-flex-block">item1</div>
  <div class="my-flex-block">item2</div>
  <div class="my-flex-block">item3</div>
</div>
.my-flex-container{
  display: flex;
}

Основные свойства Flex-контейнера. Главная и поперечная ось

Одним из основных понятий в Fleхbox являются оси.

  • Главной осью Flex-контейнера является направление, в соответствии с которым располагаются все его дочерние элементы.
  • Поперечной осью называется направление, перпендикулярное главной оси.

Главная ось в ltr локали по умолчанию располагается слева направо. Поперечная — сверху вниз. Направление главной оси Flex-контейнера можно задавать, используя базовое CSS свойство flex-direction.

flex-direction — направление главной оси

Доступные значения flex-direction:

  • row (значение по умолчанию): слева направо (в rtl справа налево)
  • row-reverse: справа налево (в rtl слева направо)
  • column: сверху вниз
  • column-reverse: снизу вверх

justify-content — выравнивание по главной оси

CSS свойство justify-content определяет то, как будут выровнены элементы вдоль главной оси.

Доступные значения justify-content:

  • flex-start (значение по умолчанию): блоки прижаты к началу главной оси
  • flex-end: блоки прижаты к концу главной оси
  • center: блоки располагаются в центре главной оси
  • space-between: первый блок располагается в начале главной оси, последний блок — в конце, все остальные блоки равномерно распределены в оставшемся пространстве.
  • space-around: все блоки равномерно распределены вдоль главной оси, разделяя все свободное пространство поровну.

align-items — выравнивание по поперечной оси

CSS свойство align-items определяет то, как будут выровнены элементы вдоль поперечной оси.

Доступные значения align-items:

  • flex-start: блоки прижаты к началу поперечной оси
  • flex-end: блоки прижаты к концу поперечной оси
  • center: блоки располагаются в центре поперечной оси
  • baseline: блоки выровнены по их baseline
  • stretch (значение по умолчанию): блоки растянуты, занимая все доступное место по поперечной оси, при этом все же учитываются min-width/max-width, если таковые заданы.

СSS свойства flex-direction, justify-content, align-items должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.

Многострочная организация блоков внутри Flex-контейнера

flex-wrap

Все примеры, которые мы приводили выше, были построены с учетом однострочного (одностолбцового) расположения блоков. Надо сказать, что по умолчанию Flex-контейнер всегда будет располагать блоки внутри себя в одну линию. Однако спецификацией также поддерживается многострочный режим. За многострочность внутри flex-контейнера отвечает CSS свойство flex-wrap.

Доступные значения flex-wrap:

  • nowrap (значение по умолчанию): блоки расположены в одну линию слева направо (в rtl справа налево)
  • wrap: блоки расположены в несколько горизонтальных рядов (если не помещаются в один ряд). Они следуют друг за другом слева направо (в rtl справа налево)
  • wrap-reverse: то же, что и wrap, но блоки располагаются в обратном порядке.

flex-flow — удобное сокращение для flex-direction + flex-wrap

По сути,flex-flow предоставляет возможность в одном свойстве описать направление главной и многострочность поперечной оси. По умолчанию flex-flow: row nowrap.

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

/* тобто ... */

.my-flex-block{
  flex-direcrion:column;
  flex-wrap: wrap;
}

/* це те ж саме, що ... */

.my-flex-block{
  flex-flow: column wrap;
}

align-content

Существует также свойство align-content, которое определяет то, каким образом образовавшиеся ряды блоков будут выровнены по вертикали и как они поделят между собой все пространство Flex-контейнера.

Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse;)

Доступные значения align-content:

  • flex-start: ряды блоков прижаты к началу flex-контейнера.
  • flex-end: ряды блоков прижаты к концу flex-контейнера
  • center: ряды блоков находятся в центре flex-контейнера
  • space-between: первый ряд блоков располагается в начале flex-контейнера, последний ряд блоков блок — в конце, все остальные ряды равномерно распределены в оставшемся пространстве.
  • space-around: ряды блоков равномерно распределены в от начала до конца flex-контейнера, разделяя все свободное пространство поровну.
  • stretch (значение по умолчанию):ряды блоков растянуты, чтобы занять все имеющееся пространство.

СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.

CSS правила для дочерних элементов flex-контейнера (flex-блоков)

flex-basis — базовый размер отдельно взятого flex-блока

Задает изначальный размер по главной оси для flex-блока до того, как к нему будут применены преобразования, основанные на других flex-факторах. Может быть задан в любых единицах измерения длинны (px, em, %, …) или auto(по умолчанию). Если задан как auto — за основу берутся размеры блока (width, height), которые, в свою очередь, могут зависеть от размера контента, если не указаны явно.

flex-grow — «жадность» отдельно взятого flex-блока

Определяет то, насколько отдельный flex-блок может быть больше соседних элементов, если это необходимо.

flex-grow принимает безразмерное значение ( по умолчанию 0)

Пример 1:

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:1, то они будут одинакового размера
  • Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные

Пример 2:

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:3, то они будут одинакового размера
  • Если один из них имеет flex-grow:12, то он будет в 4 раза больше, чем все остальные

Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень «жадности» по отношению к другим flex-блокам того же уровня.

flex-shrink — фактор «сжимаемости» отдельно взятого flex-блока

Определяет, насколько flex-блок будет уменьшаться относительно соседних эдементов внутри flex-контейнера в случае недостатка свободного места. По умолчанию равен 1.

flex — короткая запись для свойств flex-grow, flex-shrink и flex-basis

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

/* тобто ... */

.my-flex-block{
  flex-grow:12;
  flex-shrink:3;
  flex basis: 30em;
}

/* це те ж саме, що ... */

.my-flex-block{
  flex: 12 3 30em;
}

align-self — выравнивание отдельно взятого flex-блока по поперечной оси

Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.

Доступные значения align-self (те же 5 вариантов, что и для align-items)

  • flex-start: flex-блок прижат к началу поперечной оси
  • flex-end: flex-блок прижат к концу поперечной оси
  • center: flex-блок располагаются в центре поперечной оси
  • baseline: flex-блок выравнен по baseline
  • stretch (значение по умолчанию): flex-блок растянут, чтобы занять все доступное место по поперечной оси, при этом учитываются min-width/max-width, если таковые заданы.

order — порядок следования отдельно взятого flex-блока внутри flex-контейнера

По умолчанию все блоки будут следовать друг за другом в порядке, заданном в HTML. Однако этот порядок можно изменить с помощью свойства order. Оно задается целым числом и по умолчанию равно 0.

Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.

<div class="my-flex-container">
  <div class="my-flex-block" style="order: 5" >item1</div>
  <div class="my-flex-block" style="order: 10">item2</div>
  <div class="my-flex-block" style="order: 5" >item3</div>
  <div class="my-flex-block" style="order: 5" >item4</div>
  <div class="my-flex-block" style="order: 0" >item5</div>
</div>

В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2.

margin: auto — по вертикали. Мечты сбываются!

Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!

.my-flex-container {
  display: flex;
  height: 300px; /* Або що завгодно */
}

.my-flex-block {
  width: 100px;  /* Або що завгодно */
  height: 100px; /* Або що завгодно */
  margin: auto;  /* Магія! Блок відцентрований по вертикалі та горизонталі! */
}

Вещи, которые следует помнить

  1. Не следует использовать flexbox там, где в этом нет необходимости.
  2. Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
  3. Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
  4. Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
  5. Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
  6. flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.).
Придбати подарунковий сертифікат

Придбати подарунковий сертифікат

Gift certificate background image Gift certificate background image