Перейти к содержимому
Тема 13 из 15
Теория

Flexbox

Зачем это нужно

Поставить элементы в ряд, разнести по краям, выровнять по центру по вертикали — раньше это были мучения с float и таблицами. Flexbox («гибкие коробки») решает такие задачи парой строк. Шапка сайта, ряд карточек, кнопки в строку, центрирование чего угодно — всё это flex.

Контейнер и элементы

Flexbox включается у родителя:

<style>
  .row { display: flex; }
  .row div { padding: 20px; background: gold; }
</style>
<div class="row">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Результат: три жёлтых блока в ряд, хотя div обычно встают друг под другом.

  • .row — flex-контейнер;
  • его прямые дети — flex-элементы. Внуки на flex не реагируют.

Две оси

У контейнера есть главная ось — вдоль неё идут элементы — и поперечная под прямым углом.

.row { flex-direction: row; }    /* главная ось → слева направо (по умолчанию) */
.col { flex-direction: column; } /* главная ось ↓ сверху вниз */

Это важно: свойства выравнивания работают относительно осей, а не «по горизонтали»:

  • justify-content — вдоль главной оси;
  • align-items — вдоль поперечной.

justify-content: по главной оси

.row { display: flex; justify-content: space-between; }
Значение Что делает
flex-start всё в начале (по умолчанию)
flex-end всё в конце
center по центру
space-between первый у начала, последний у конца, остальное поровну между
space-around одинаковое место вокруг каждого
space-evenly все промежутки одинаковые, включая края

Результат с space-between: блок 1 у левого края, блок 3 у правого, блок 2 посередине.

align-items: по поперечной оси

.row { display: flex; align-items: center; height: 200px; }
Значение Что делает
stretch растянуть на всю высоту (по умолчанию)
flex-start / flex-end прижать к началу / к концу
center по центру

Результат: блоки стоят посередине по высоте 200-пиксельного контейнера.

Идеальное центрирование — то, чего долго не хватало вебу:

.screen {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Результат: содержимое ровно в центре экрана и по горизонтали, и по вертикали.

gap: промежутки

.row { display: flex; gap: 16px; }

Результат: между элементами по 16px — но не по краям. Раньше для этого ставили margin каждому элементу и потом убирали у последнего; gap проще.

flex-wrap: перенос

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

.cards { display: flex; flex-wrap: wrap; gap: 10px; }
.cards div { width: 200px; }

Результат: карточки по 200px в ряд; не влезающие уходят на следующую строку. На узком экране получится одна колонка, на широком — четыре.

Свойства элементов: flex-grow, flex-shrink, flex-basis

Эти свойства задаются детям:

  • flex-basis — «желаемый» размер вдоль главной оси;
  • flex-grow — какую долю свободного места забрать (0 — не расти);
  • flex-shrink — можно ли сжиматься, если места мало (0 — нельзя).
.sidebar { flex: 0 0 250px; } /* не расти, не сжиматься, 250px */
.main    { flex: 1; }          /* забрать всё свободное место */

Результат: боковая колонка ровно 250px, а основная часть растягивается на всю оставшуюся ширину.

Сокращение flex: grow shrink basis. Если у двух элементов flex: 1 и flex: 2, второй получит вдвое больше свободного места.

Отдельному элементу можно задать своё выравнивание поперёк: align-self: flex-end;. А margin-left: auto у элемента «отталкивает» его к правому краю.

Как это работает внутри

Браузер сначала ставит элементы по их flex-basis (или ширине содержимого), потом считает, сколько места осталось. Если место есть — делит его по flex-grow; если не хватает — отнимает по flex-shrink. Затем раскладывает элементы вдоль главной оси по justify-content и выравнивает поперёк по align-items.

Частые ошибки

  1. display: flex у элементов, а не у контейнера. Flex включается у родителя.
  2. Ждут, что сработает на внуков. Flex действует только на прямых детей. Вложенный ряд — ещё один flex-контейнер.
  3. Путают оси. С flex-direction: column justify-content работает по вертикали, а align-items — по горизонтали.
  4. align-items: center «не работает». У контейнера нет высоты больше содержимого — центрировать не в чем.
  5. Карточки сплющились. Без flex-wrap: wrap элементы сжимаются в одну строку.

Шпаргалка

Свойство (у кого) Что делает
display: flex (родитель) включить flexbox
flex-direction: row / column направление главной оси
justify-content выравнивание по главной оси
align-items выравнивание по поперечной оси
gap: 16px промежутки между элементами
flex-wrap: wrap переносить на новую строку
flex: 1 (ребёнок) забрать свободное место
flex: 0 0 200px (ребёнок) фиксированный размер
align-self (ребёнок) своё выравнивание поперёк

В ряд с промежутком

Лёгкая+10 XP

Поставь три карточки внутри .row в один ряд: сделай .row flex-контейнером и задай промежуток между карточками 20px.

Подключи коннектор, чтобы решать задачи

Код задач выполняется на твоём компьютере — так быстрее и надёжнее, чем в браузере. Для этого нужна бесплатная программа-коннектор CodeWithMe. Подключить её нужно один раз.

Ищем коннектор на этом компьютере…

  1. 1
    Скачай коннектор для своей системы (Windows, macOS или Linux).Скачать коннекторНа странице загрузки выбери файл со своей системой в названии, например windows-amd64.
  2. 2Запусти его и выбери папку, где будут лежать твои решения. Python и Node.js он поставит туда сам, когда понадобится.
  3. 3
    Введи ниже код из 6 цифр — он написан в окне коннектора («Код для сайта CodeWithMe»). Если браузер спросит про доступ к локальной сети — разреши.

Коннектор открытый (исходный код на GitHub), работает только на твоём компьютере и выполняет код лишь после ввода кода сопряжения.