Флексбокс «на пальцах»

Вкратце напомню о флекс‑контейнере и флекс‑элементах. Флексбокс — это набор ЦСС‑свойств для гибкой раскладки элементов на странице или в отдельном блоке. Чтобы включить флексбокс, нужно задать элементу display: flex. Тогда элемент станет флекс‑контейнером, а все вложенные в него элементы станут флекс‑элементами.

Флексбокс «на пальцах»

По умолчанию флекс‑элементы занимают ровно столько места, сколько нужно их содержимому. Чтобы управлять их размерами, растягивая, уменьшая или занимая определённую долю, есть три ЦСС‑свойства: flex-basis, flex-grow и flex-shrink.

flex‑basis

flex-basis определяет начальный размер элемента перед применением к нему flex-grow и flex-shrink. Считайте, что flex-basis задаёт идеальный или предположительный размер элемента, который изменится, когда браузер упакует элемент во флекс‑контейнер. Смотрите:

Три элемента с flex-basis: 50% переполняют контейнер, потому что им не разрешено уменьшаться
Три элемента с flex-basis: 50% и flex-shrink: 1 вписываются в контейнер, равномерно уменьшаясь в размерах
Элемент с flex-basis: 50% занимает ровно половину контейнера, потому что ему не разрешено увеличиваться
Элемент с flex-basis: 50% и flex-grow: 1 вытягивается, чтобы занять всё доступное пространство

flex-basis часто используют для вёрстки по сетке. Например, так может выглядеть простейшая сетка на 4 колонки:

style.css
.row {
  /*
  * .row — флекс-контейнер, этаж сетки.
  */
  display: flex;
  /*
  * Флекс-элементы будут раскладываться
  * слева направо.
  */
  flex-direction: row;
  /*
  * Прижимаем флекс-элементы к левому краю.
  */
  justify-content: flex-start;
  /*
  * Если места для элементов не хватает,
  * запрещаем их перенос на следующую строку.
  */
  flex-wrap: nowrap;
  /*
  * Компенсируем межколонник отрицательными
  * отступами влево-вправо. */
  margin: 0 -10px;
}
​
/*
* Флекс-элементы на одну, две, три
* и четыре колонки.
*/
.col-1,
.col-2,
.col-3,
.col-4 {
  /*
  * flex-grow: 0 не даёт элементу
  * растягиваться больше указанного размера.
  */
  flex-grow: 0;
  /*
  * flex-shrink: 0 не даёт элементу
  * уменьшаться меньше указанного размера.
  */
  flex-shrink: 0;
  padding: 0 10px;
}
​
.col-1 {
  flex-basis: 25%;
}
​
.col-2 {
  flex-basis: 50%;
}
​
.col-3 {
  flex-basis: 75%;
}
​
.col-4 {
  flex-basis: 100%;
}
index.html
<div class="row">
  <div class="col-4">
    <!-- Колонка на всю ширину страницы -->
  </div>
</div>
​
<div class="row">
  <div class="col-3">
    <!-- Колонка на три четверти страницы -->
  </div>
  <div class="col-1">
    <!-- Колонка на четверть страницы -->
  </div>
</div>
​
<div class="row">
  <div class="col-1">
    <!-- Колонка на четверть страницы -->
  </div>
  <div class="col-1"></div>
  <div class="col-1"></div>
  <div class="col-1"></div>
</div>

flex‑grow

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

flex-grow: 1
Один элемент займёт всю доступную ширину контейнера.

flex-grow: 1 и flex-grow: 1
Два элемента поделят контейнер пополам.

flex-grow: 2 и flex-grow: 1
Два элемента поделят контейнер в соотношении 2:1.

Считайте, что flex-grow задаёт пропорцию, по которой элементы делят контейнер.

Например, чтобы собрать адаптивные колонки, равномерно делящие доступное пространство, используют flex-grow: 1:

style.css
.cols {
  display: flex;
  flex: 1;
  flex-wrap: nowrap;
  gap: 18px;
}
.cols > * {
  /*
  * flex: 1 — краткая запись для:
  *   flex-grow: 1;
  *   flex-shrink: 1;
  *   flex-basis: 0;
  */
  flex: 1;
}
index.html
<div class="cols">
  <div>Первая колонка</div>
  <div>Вторая колонка</div>
  <div>Третья колонка</div>
</div>
Первая колонка
Вторая колонка
Третья колонка
Четвертая колонка

Чтобы адаптировать такие колонки к мобильным экранам, достаточно поменять им flex-basis и разрешить перенос:

/* Считаем, что у мобильных экраны шириной менее 961 пикселя */
@media screen and (max-width: 961px) {
  .cols {
    flex-wrap: wrap;
  }
  .cols > * {
    flex-basis: 100%;
  }
}
Первая колонка
Вторая колонка
Третья колонка
Четвертая колонка

Иногда при перестроении колонок нужно поменять их порядок. Для этого используют order:

@media screen and (max-width: 961px) {
  .cols > *:nth-child(2) {
    /* Ставим вторую колонку в начало списка */
    order: -1;
  }
}
Первая колонка
Вторая колонка
Третья колонка
Четвертая колонка

flex‑shrink

flex-shrink определяет «сжимаемость» элемента: как сильно элемент уменьшается, когда в контейнере не хватает места.

Если ширина контейнера 100 пикселей, а в нём два элемента с flex-basis: 75px, то контейнеру не хватит 50 пикселей. Он отнимет недостающие пиксели у флекс‑элементов пропорционально: элементы с flex-shrink: 4 и flex-shrink: 1 получат −40 и −10 пикселей.

Что запомнить

Чтобы управлять размерами элементов внутри флекс‑контейнера, используют flex-basis, flex-grow и flex-shrink

Чтобы управлять «жадностью» флекс‑элементов, используют flex-grow. Чтобы управлять «сжимаемостью» — flex-shrink

Чтобы поменять порядок отдельных флекс‑элементов, используют order

Ещё по теме

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.
Веб‑разработка
Отправить
Поделиться
Запинить

Рекомендуем другие советы