20 Модуль 4 Коробки и раскладка 17 мин урок 20 из 25

Flexbox: раскладка вдоль оси

Одна строка превращает контейнер в гибкий ряд: выравнивание, распределение места, переносы и знаменитое flex: 1.

Что ты научишься делать

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

#Одна строка меняет всё

display: flex пишется родителю. После этого все его прямые дети становятся флекс-элементами и выстраиваются в ряд.

Зазоров между ними нет, высота выравнивается автоматически, расстояние задаётся одним свойством. Всё то, чего так не хватало с inline-block.

Так не надо

.menu li {
  display: inline-block;
  margin-right: 16px;
}
/* + разметка без переносов строк */

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

Так надо

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

Два свойства вместо возни. Разметку можно писать как удобно, gap ставит расстояние только между элементами.

#Две оси

Вся логика флексов держится на понятии осей. Главная ось — направление, вдоль которого выстраиваются элементы. Поперечная — перпендикулярная ей.

По умолчанию главная ось горизонтальная. Свойство flex-direction: column поворачивает её вертикально — и тогда все остальные свойства меняются местами.

СвойствоОсьЧто делает
justify-contentГлавнаяРаспределяет элементы вдоль оси
align-itemsПоперечнаяВыравнивает элементы поперёк
align-contentПоперечнаяРаспределяет строки, когда включён перенос
gapОбеРасстояние между элементами

Площадка Flexbox

Все свойства флекс-контейнера кнопками, элементы перелетают в новые позиции.

СвойствоЧто делает
flex-directionЗадаёт главную ось: строка или колонка
justify-contentРаскладывает вдоль главной оси
align-itemsВыравнивает поперёк главной оси
gapРасстояние между элементами
flex-wrapРазрешает перенос на новую строку

#justify-content: вдоль оси

ЗначениеРезультат
flex-startВсё прижато к началу (по умолчанию)
centerПо центру
flex-endПрижато к концу
space-betweenКрайние по краям, промежутки одинаковые
space-aroundУ каждого свой отступ; между элементами он вдвое больше, чем по краям
space-evenlyВсе промежутки, включая краевые, одинаковые

#align-items: поперёк оси

По умолчанию стоит stretch: все элементы растягиваются на высоту самого высокого. Именно поэтому карточки в ряду сами получаются одинаковой высоты — этого годами добивались костылями.

Остальные значения: flex-start, center, flex-end и baseline — выравнивание по базовой линии текста, а не по краю блока.

#Центрирование, за которое боролись двадцать лет

CSSИдеальный центр
.hero {  display: flex;  justify-content: center;  /* по горизонтали */  align-items: center;      /* по вертикали */  min-height: 400px;}

#Как элементы делят место

У самих флекс-элементов есть три свойства. Обычно их пишут вместе, сокращением flex.

  • flex-grow — насколько жадно элемент забирает свободное место. 0 — не растёт.
  • flex-shrink — насколько охотно сжимается, когда места не хватает. 0 — не сжимается.
  • flex-basis — базовый размер до распределения. auto — по содержимому.
CSSЧто означают частые записи
.a { flex: 1; }          /* grow 1, shrink 1, basis 0 — делят место поровну */.b { flex: auto; }       /* grow 1, shrink 1, basis auto — с учётом содержимого */.c { flex: none; }       /* не растёт и не сжимается — фиксированный */.d { flex: 1 1 240px; }  /* растёт, сжимается, стартует с 240px */
Поменяй flex у средней колонки
В песочницу

#Перенос на новую строку

По умолчанию флекс-элементы не переносятся: они сжимаются до последнего и вылезают за край. flex-wrap: wrap разрешает перенос.

Связка flex-wrap: wrap плюс flex: 1 1 240px даёт простую отзывчивую сетку без единого медиазапроса: элементы стараются быть не уже 240 пикселей, а когда не помещаются — переносятся.

Сетка карточек без медиазапросов
В песочницу

#order: порядок только для глаз

Свойство order меняет положение элемента в ряду, не трогая разметку. Соблазн большой: подвинуть картинку влево одной строкой вместо перестановки тегов.

Ловушка в том, что порядок меняется только визуально. Клавиша Tab и программы чтения с экрана идут по исходному коду, поэтому фокус будет прыгать: с виду вторая кнопка получит фокус первой. Для мелких перестановок в одном ряду это терпимо, для порядка полей формы или пунктов меню — нет.

Правило простое: если перестановка меняет смысл последовательности, менять надо разметку, а не order.

#Три приёма, которые нужны постоянно

CSSШпаргалка
/* 1. Прижать элемент вправо в шапке */.header__nav {  margin-left: auto;   /* auto съедает всё свободное место слева */}/* 2. Прижать подвал карточки книзу, какой бы длины ни был текст */.card {  display: flex;  flex-direction: column;}.card__footer {  margin-top: auto;}/* 3. Поменять порядок, не трогая разметку */.sidebar { order: -1; }
Шапка сайта на флексах
В песочницу

Где спотыкаются почти все

display: flex написан ребёнку вместо родителя

Почему Флексом становится контейнер, а не элементы внутри. Правило на ребёнке просто делает флекс-контейнером его самого.

Как надо Пиши display: flex тому элементу, чьих детей нужно разложить.

Элементы не переносятся и вылезают за край

Почему По умолчанию flex-wrap: nowrap: браузер сжимает элементы, а когда сжимать некуда — они выходят за границы.

Как надо Добавь flex-wrap: wrap.

Отступы между элементами заданы через margin

Почему У крайних элементов появляется лишний отступ, приходится писать :last-child и считать края.

Как надо Одно свойство gap у контейнера — расстояние только между элементами.

Длинный текст растянул колонку и сломал ряд

Почему У флекс-элементов min-width по умолчанию равен auto: элемент не может стать уже своего содержимого.

Как надо Добавь проблемному элементу min-width: 0 — теперь он сможет сжаться, а текст перенесётся.

Флекс-контейнер flex container
Элемент с display: flex. Управляет раскладкой своих детей.
Флекс-элемент flex item
Прямой ребёнок флекс-контейнера.
Главная ось main axis
Направление, вдоль которого выстраиваются элементы. Задаётся flex-direction.
Поперечная ось cross axis
Перпендикулярная главной. По ней работает align-items.
gap gap
Расстояние между элементами внутри контейнера, без отступов по краям.

Проверь себя

  1. Какому элементу пишут <code>display: flex</code>?

    Флекс-контейнером становится родитель, а раскладываются его прямые дети.

  2. Что делает <code>align-items: center</code> при <code>flex-direction: row</code>?

    При горизонтальной главной оси поперечная — вертикальная. По горизонтали центрирует <code>justify-content</code>.

  3. Что означает <code>flex: 1</code>?

    Это сокращение от <code>flex: 1 1 0</code>: растёт, сжимается, стартует с нуля. Все такие элементы делят место поровну.

  4. Как прижать последний элемент шапки к правому краю?

    <code>auto</code> у отступа съедает всё свободное место — элемент уезжает вправо, а остальные остаются на местах.

  5. Длинное слово растянуло колонку и сломало ряд. Что поможет?

    У флекс-элементов <code>min-width</code> по умолчанию <code>auto</code>: они не сжимаются уже содержимого. Явный ноль снимает это ограничение.

Задание

Шапка и сетка карточек

Собери две вещи на флексах:

  • шапка: логотип слева, меню и кнопка прижаты вправо, всё выровнено по центру по вертикали, расстояние между элементами задано через gap;
  • сетка: карточки в ряд, переносятся при нехватке места, каждая не уже 200px и растягивается.

Никаких float и inline-block.

Открыть в песочнице
    Подсказка 1

    Шапка: .header { display: flex; align-items: center; gap: 20px; }

    Подсказка 2

    Меню вправо: .nav { display: flex; gap: 16px; margin-left: auto; }

    Подсказка 3

    Сетка: .grid { display: flex; flex-wrap: wrap; gap: 12px; } и .card { flex: 1 1 200px; }

    Показать решение
    HTMLindex.html
    <header class="header">  <a class="logo" href="#">Полка</a>  <nav class="nav">    <a href="#">Меню</a>    <a href="#">О нас</a>  </nav>  <a class="btn" href="#">Заказать</a></header><div class="grid">  <article class="card"><h3>Эспрессо</h3><p>120 ₽</p></article>  <article class="card"><h3>Капучино</h3><p>190 ₽</p></article>  <article class="card"><h3>Раф</h3><p>240 ₽</p></article></div>
    CSSstyle.css
    * { box-sizing: border-box; }.header {  display: flex;  align-items: center;  gap: 20px;  padding: 14px 18px;  background: #14173a;  border-radius: 12px;  margin-bottom: 16px;}.nav {  display: flex;  gap: 16px;  margin-left: auto;}.logo { color: #fff; font-weight: 700; text-decoration: none; }.nav a { color: #c6c9de; text-decoration: none; font-size: 14px; }.btn { padding: 8px 16px; color: #fff; background: #6544e0; border-radius: 999px; text-decoration: none; font-size: 14px; }.grid {  display: flex;  flex-wrap: wrap;  gap: 12px;}.card {  flex: 1 1 200px;  padding: 18px;  background: #f5f5fa;  border-radius: 12px;}.card h3 { margin: 0 0 8px; font-size: 16px; }.card p { margin: 0; font-weight: 700; }

    Проверь себя