Flexbox: выравнивание без слёз

Flexbox: выравнивание без слёз

Flexbox - это когда ты перестаёшь ставить float и начинаешь выравнивать элементы нормально.

Основная идея

Flexbox работает с двумя сущностями: контейнер (flex container) и элементы (flex items). Контейнер управляет расположением своих прямых потомков.

.container {
  display: flex;
}

Все прямые дети .container становятся flex-элементами и выстраиваются в строку.

Оси

У Flexbox две оси:

Главная ось (main axis) → по умолчанию горизонтальная
Поперечная ось (cross axis) ↓ перпендикулярна главной

Flexbox: две оси, justify-content по главной и align-items по поперечной

flex-direction определяет направление главной оси:

.row { flex-direction: row; }            /* → (по умолчанию) */
.row-reverse { flex-direction: row-reverse; }  /* ← */
.column { flex-direction: column; }       /* ↓ */
.column-reverse { flex-direction: column-reverse; } /* ↑ */

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

.container { display: flex; justify-content: flex-start; }
flex-start:      [A][B][C]____________
flex-end:        ____________[A][B][C]
center:          ______[A][B][C]______
space-between:   [A]______[B]______[C]
space-around:    __[A]____[B]____[C]__
space-evenly:    ___[A]___[B]___[C]___

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

.container {
  display: flex;
  height: 200px;
  align-items: center; /* выравнивание по вертикали */
}
flex-start:   A B C
              _ _ _
              _ _ _

center:       _ _ _
              A B C
              _ _ _

flex-end:     _ _ _
              _ _ _
              A B C

stretch:      A B C    (элементы растягиваются на всю высоту)
              A B C
              A B C

stretch - значение по умолчанию. Элементы занимают всю доступную высоту.

gap - расстояние между элементами

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

Раньше для расстояния между элементами использовали margin. С gap не нужно убирать отступ у первого/последнего элемента - он работает только между ними.

/* Разные gap по осям */
.grid {
  display: flex;
  flex-wrap: wrap;
  row-gap: 24px;
  column-gap: 16px;
}

flex-wrap - перенос строк

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

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
Без `wrap` карточки сожмутся до нечитаемого размера. С `wrap` - красиво переносятся на следующую строку.

Свойства flex-элементов

flex-grow - занять свободное место

.sidebar { flex: 0 0 250px; }  /* фиксированная ширина */
.content { flex: 1; }          /* занимает всё остальное */

flex-shrink - как сжиматься

.logo { flex-shrink: 0; }  /* не сжимать логотип */

flex-basis - начальный размер

.card { flex-basis: 300px; }  /* начальная ширина 300px */

Сокращение flex

.item { flex: 1; }           /* grow: 1, shrink: 1, basis: 0 */
.item { flex: 0 0 200px; }   /* grow: 0, shrink: 0, basis: 200px */
.item { flex: 1 1 auto; }    /* grow: 1, shrink: 1, basis: auto */

align-self - индивидуальное выравнивание

.container { display: flex; align-items: flex-start; }
.special { align-self: flex-end; } /* только этот элемент внизу */

order - изменить порядок

.first { order: -1; }  /* появится первым */
.last { order: 1; }    /* появится последним */

Визуальный порядок меняется, но порядок в DOM остаётся прежним (важно для доступности).

Практические паттерны

TopBar: логотип слева, кнопки справа

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px;
  height: 64px;
}

Центрирование (идеальное)

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

Карточки в ряд с переносом

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.card {
  flex: 1 1 300px; /* минимум 300px, растягиваются равномерно */
  max-width: 400px;
}

Sidebar + Content

.layout {
  display: flex;
  gap: 24px;
}

.sidebar {
  flex: 0 0 250px; /* фиксированный sidebar */
}

.content {
  flex: 1; /* контент занимает остальное */
  min-width: 0; /* предотвращает overflow */
}
По умолчанию flex-элементы не сужаются меньше своего контента. Если текст или код слишком длинный - элемент вылезет за границы. `min-width: 0` разрешает сжатие.

Мини-задание

  • Сделай TopBar: логотип слева, навигация по центру, кнопки справа
  • Сверстай карточки в ряд с flex-wrap: wrap и gap: 24px
  • Сделай layout: фиксированный sidebar (250px) + растягивающийся контент
  • Центрируй блок идеально по вертикали и горизонтали
  • Поэкспериментируй с flex-direction: column для мобильного меню

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