Перейти к содержанию
Educora
Продвинутый20 мин8 / 10

Flexbox: раскладка элементов в линию

С помощью Flexbox выстраивай элементы в строку или столбец, распределяй пространство между ними, центрируй их и подстраивай под доступное место.

Проверь себя
В этом уроке ты узнаешь
  • Создавать флекс-контейнер и объяснять главную и поперечную оси
  • Выравнивать элементы с помощью justify-content, align-items и gap
  • Центрировать элемент в обоих направлениях
  • Строить гибкие меню и ряды карточек с помощью flex, flex-wrap и margin-left: auto

Вверху почти каждого сайта одна и та же картина: слева логотип, справа меню, всё на одной линии и по центру по вертикали. Долгие годы вертикальное центрирование было знаменитой головной болью веб-разработчиков. Flexbox решает это в несколько строк.

Флекс-контейнер и оси

Когда родителю задают display: flex, он становится флекс-контейнером, а его прямые потомки — флекс-элементами. Элементы выстраиваются вдоль главной оси: по умолчанию это горизонталь слева направо (flex-direction: row). Перпендикулярная ей ось называется поперечной. Если написать flex-direction: column, оси меняются местами: элементы выстраиваются сверху вниз.

HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 12px; }
  .box { padding: 8px; margin-bottom: 12px; background: #f1f5f9; border-radius: 8px; }
  .flex { display: flex; gap: 8px; }
  .item { padding: 10px 16px; background: #818cf8; color: white; border-radius: 6px; }
</style>

<p>Without flex: blocks stack.</p>
<div class="box">
  <div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>

<p>With display: flex: one row.</p>
<div class="box flex">
  <div class="item">1</div><div class="item">2</div><div class="item">3</div>
</div>
Предпросмотр
Добавь в правило .flex строку flex-direction: column; — элементы снова встанут друг под другом, но промежуток gap между ними сохранится.

Выравнивание: `justify-content` и `align-items`

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

HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 8px; font-size: 13px; }
  .row { display: flex; margin: 2px 0 8px; background: #f1f5f9; border-radius: 6px; }
  .row div { width: 40px; margin: 3px; padding: 4px 0; text-align: center;
             background: #34d399; border-radius: 4px; }
  .start { justify-content: flex-start; }
  .center { justify-content: center; }
  .end { justify-content: flex-end; }
  .between { justify-content: space-between; }
  .evenly { justify-content: space-evenly; }
</style>

<code>flex-start</code><div class="row start"><div>1</div><div>2</div><div>3</div></div>
<code>center</code><div class="row center"><div>1</div><div>2</div><div>3</div></div>
<code>flex-end</code><div class="row end"><div>1</div><div>2</div><div>3</div></div>
<code>space-between</code><div class="row between"><div>1</div><div>2</div><div>3</div></div>
<code>space-evenly</code><div class="row evenly"><div>1</div><div>2</div><div>3</div></div>
Предпросмотр
space-between прижимает крайние элементы к краям, а space-evenly делает все промежутки равными. Задай одному .row значение space-around и найди отличие.
СвойствоЗначенияЧто делает
flex-directionrow, columnнаправление главной оси
justify-contentflex-start, center, space-between…размещение вдоль главной оси
align-itemsstretch, center, flex-start, flex-endвыравнивание по поперечной оси (по умолчанию stretch — растягивание)
flex-wrapnowrap, wrapперенос на новую строку, когда не хватает места
gap8px, 1rem…расстояние между элементами
Все эти свойства задают флекс-контейнеру.
HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 12px; }
  .stage {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 180px;
    background: linear-gradient(135deg, #a5b4fc, #f9a8d4);
    border-radius: 12px;
  }
  .badge { padding: 14px 22px; background: white; border-radius: 10px; font-weight: 700; }
</style>

<div class="stage">
  <div class="badge">Perfectly centered 🎯</div>
</div>
Предпросмотр
Поменяй align-items на flex-end, потом на flex-start. А linear-gradient — это фон с плавным переходом между двумя цветами.

Гибкие размеры: `flex` и `flex-wrap`

Слово «flex» (гибкий) в названии Flexbox означает, что элементы могут расти и сжиматься под свободное место. Этим управляет свойство flex, которое задают элементу. flex: 1 говорит элементу: «займи всё оставшееся место». Если у нескольких элементов flex: 1, они делят свободное место поровну. Полная запись flex: 1 1 140px — это три значения: рост (flex-grow), сжатие (flex-shrink) и исходный размер (flex-basis).

HTML
<style>
  body { font-family: system-ui, sans-serif; margin: 0; }
  nav { display: flex; align-items: center; gap: 16px; padding: 12px 16px; background: #1e293b; }
  nav a { color: #e2e8f0; text-decoration: none; }
  .logo { font-weight: 800; color: #fbbf24; }
  .login { margin-left: auto; padding: 6px 14px; background: #fbbf24; color: #1e293b; border-radius: 6px; }
  .page { display: flex; gap: 12px; padding: 12px; }
  .side { width: 110px; padding: 10px; background: #e0e7ff; border-radius: 8px; }
  .content { flex: 1; padding: 10px; background: #f1f5f9; border-radius: 8px; }
</style>

<nav>
  <span class="logo">MySite</span>
  <a href="#">Home</a>
  <a href="#">Blog</a>
  <a href="#" class="login">Log in</a>
</nav>
<div class="page">
  <aside class="side">Side menu: 110px</aside>
  <main class="content">flex: 1 takes all the space that is left.</main>
</div>
Предпросмотр
В меню .login прижат вправо, потому что margin-left: auto собирает всё свободное место слева от него. Задай flex: 1 и для .side — две колонки станут одинаковыми.

По умолчанию флекс-элементы остаются в одной строке и при необходимости сжимаются. flex-wrap: wrap позволяет им переноситься на новую строку, когда места не хватает. Вместе с flex: 1 1 140px это даёт ряд карточек, который хорошо выглядит и на телефоне, и на широком экране.

HTML
<style>
  body { font-family: system-ui, sans-serif; padding: 12px; background: #f8fafc; }
  .cards { display: flex; flex-wrap: wrap; gap: 12px; }
  .card { flex: 1 1 140px; padding: 12px; text-align: center;
          background: white; border: 1px solid #e2e8f0; border-radius: 10px; }
  .card span { font-size: 32px; }
  .card p { margin: 6px 0 0; }
</style>

<div class="cards">
  <div class="card"><span>🍎</span><p>Apples</p></div>
  <div class="card"><span>🍐</span><p>Pears</p></div>
  <div class="card"><span>🍇</span><p>Grapes</p></div>
  <div class="card"><span>🍑</span><p>Peaches</p></div>
  <div class="card"><span>🍋</span><p>Lemons</p></div>
</div>
Предпросмотр
Замени 140px на 250px — в строку поместится меньше карточек, остальные перенесутся. Потом удали flex-wrap: wrap и посмотри, как карточки сожмутся.

Главное

  • display: flex превращает контейнер во флекс-контейнер, а его прямых потомков — во флекс-элементы.
  • flex-direction выбирает главную ось: row — горизонтальная, column — вертикальная.
  • justify-content выравнивает по главной оси, align-items — по поперечной; gap задаёт промежутки между элементами.
  • flex: 1 заставляет элемент занять оставшееся место; flex-wrap: wrap переносит элементы на новую строку.
  • Центрирование: justify-content: center + align-items: center; сдвиг элемента в конец: margin-left: auto.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Какое правило превращает элемент во флекс-контейнер?