CSS Flexbox: полное руководство для создания современных сеток

В веб-разработке регулярно возникают задачи по созданию интерфейсов, которые должны идеально выглядеть на экранах любых размеров. Если вы устали бороться с «уплывающими» элементами, неочевидным поведением блоков при изменении размеров окна и хотите легко создавать сложные адаптивные макеты, то эта статья — для вас.

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

CSS Flexbox: полное руководство для создания современных сеток

Основы Flexbox: контейнеры, оси и display: flex

Ключевым принципом работы CSS Flexbox является взаимодействие между контейнером и его дочерними элементами (flex-элементами). Все начинается с HTML-разметки, где вы определяете контейнер, который будет управлять расположением вложенных в него блоков. Таким контейнером может быть любой элемент: <body>, <div>, <section> или <nav>. Чтобы превратить обычный HTML-элемент в flex-контейнер, ему достаточно задать одно CSS-свойство.

.container {
  display: flex; /* Это волшебная строка, включающая Flexbox */
}

Рассмотрим простой пример с пятью блоками (<div>), которые по умолчанию, будучи блочными элементами (display: block), отображаются друг под другом, занимая всю доступную ширину.

<div class="container">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="box">5</div>
</div>
.box {
  width: 80px;
  height: 80px;
  background-color: #3498db;
  margin: 5px;
  color: white;
  font-size: 24px;
  text-align: center;
  line-height: 80px;
}
/* Без Flexbox блоки идут вертикально */

После применения display: flex к контейнеру .container происходит магия: все дочерние блоки моментально выстраиваются в горизонтальный ряд (по умолчанию). Это происходит потому, что мы вышли из стандартной блочной/строчной модели и активировали flex-контекст.

.container {
  display: flex;
}

Сердцем модели Flexbox являются две оси: главная ось (main axis) и поперечная ось (cross axis). По умолчанию главная ось направлена слева направо (как строка текста), а поперечная — сверху вниз. Именно управление выравниванием и распределением элементов вдоль этих осей дает нам невиданную ранее гибкость.

Выравнивание элементов: justify-content и align-items

Свойства justify-content и align-items являются основными инструментами для выравнивания в Flexbox. Первое управляет расположением элементов вдоль главной оси, второе — вдоль поперечной. Давайте разберемся, как с их помощью решить самую известную задачу верстки — центрирование элемента.

Допустим, мы хотим расположить наши пять блоков по центру страницы. Сначала зададим контейнеру (в данном случае <body>) высоту, чтобы было видно вертикальное выравнивание.

.container {
  display: flex; /* Включаем Flexbox */
  min-height: 50vh; /* Контейнер занимает весь экран по высоте */  
}
.box { /* Стили блоков из прошлого примера */ }

justify-content для главной оси (по умолчанию — горизонтальной):

  • flex-start (значение по умолчанию): элементы прижимаются к началу оси (слева).
  • flex-end: элементы прижимаются к концу оси (справа).
  • center: элементы центрируются по главной оси. Это ответ на горизонтальное центрирование.

align-items для поперечной оси (по умолчанию — вертикальной):

  • flex-start: элементы прижимаются к началу оси (сверху).
  • flex-end: элементы прижимаются к концу оси (снизу).
  • center: элементы центрируются по поперечной оси. Это ответ на вертикальное центрирование.

Таким образом, классическое центрирование по вертикали и горизонтали достигается всего тремя строчками:

.container {
  display: flex;
  justify-content: center; /* Центр по горизонтали */
  align-items: center;     /* Центр по вертикали */
  min-height: 50vh;
}

Кроме базовых значений, justify-content имеет очень полезные значения для распределения пространства:

  • space-between: первый элемент у начала, последний у конца, остальное пространство равномерно распределено между элементами.
  • space-around: пространство распределяется вокруг каждого элемента (слева и справа). Из-за суммирования промежутков между элементами пространство там получается в два раза больше, чем по краям.
  • space-evenly: пространство распределяется равномерно между элементами и по краям контейнера.
.container {  
  justify-content: space-between; /* Элементы равномерно распределены по горизонтали */  
}

Сравнение значений justify-content

Значение Описание
flex-start Элементы сгруппированы в начале.
center Элементы сгруппированы по центру.
space-between Первый и последний элемент прижаты к краям.
space-around Равное пространство вокруг каждого элемента.
space-evenly Все промежутки (включая края) равны.

Управление направлением: flex-direction

Свойство flex-direction полностью переворачивает представление об осях в CSS Flexbox, меняя направление главной оси. Это критически важное свойство, так как оно определяет, как будут работать justify-content и align-items.

По умолчанию установлено flex-direction: row (главная ось горизонтальна). Но у него есть и другие значения:

  • row-reverse: Главная ось идет справа налево. Элементы выстраиваются в ряд, но порядок их следования обратный. flex-start теперь будет справа.
  • column: Главная ось становится вертикальной и направлена сверху вниз. Элементы выстраиваются в колонку. Теперь justify-content управляет вертикальным выравниванием, а align-items — горизонтальным.
  • column-reverse: Аналогично column, но ось направлена снизу вверх.
.container {  
  flex-direction: column; /* Блоки встанут друг под другом */
  align-items: center;    /* Теперь это центрирует их по горизонтали! */
  justify-content: center; /* А это — по вертикали */  
}

Это свойство незаменимо для создания лендингов или страниц, где весь контент должен быть выровнен по вертикали и центрирован по горизонтали.

Многострочные макеты и промежутки: flex-wrap, gap и align-content

Для создания адаптивных сеток, которые переносят элементы на новую строку, в CSS Flexbox используется свойство flex-wrap.

По умолчанию установлено nowrap — элементы будут бесконечно сжиматься, чтобы поместиться в одну строку. Значение wrap разрешает перенос на следующую строку.

.container {
  display: flex;
  flex-wrap: wrap; /* Разрешаем перенос */
  gap: 20px; /* Удобное свойство для отступов между элементами */
}
.box {
  flex: 1 1 200px; /* Блоки могут расти и сжиматься, но имеют базовый размер 200px */
  min-width: 150px; /* Минимальная ширина, до которой можно сжиматься */
}

При использовании flex-wrap: wrap у нас появляется несколько flex-линий (рядов). Свойство align-items будет выравнивать элементы внутри каждой такой линии по поперечной оси. Чтобы управлять распределением всех линий относительно контейнера по поперечной оси, используется свойство align-content. Оно принимает те же значения, что и justify-content (flex-start, center, space-between и т.д.), но применяется ко всему набору строк.

.container {
  display: flex;
  flex-wrap: wrap;
  align-content: center; /* Все строки блоков центрируются по вертикали */
  justify-content: center; /* Элементы в строках центрируются по горизонтали */
  align-items: center; /* Элементы центрируются внутри своей строки по вертикали */
  min-height: 100vh;
  gap: 20px;
}

Свойство gap (и его производные row-gap, column-gap) — это современный и чистый способ задать отступы между элементами внутри flex- (или grid-) контейнера, избавляющий от необходимости использовать отрицательные margin или сложные селекторы.

Гибкое изменение размеров: flex-grow, flex-shrink и flex-basis

Настоящую мощь и адаптивность Flexbox дают свойства flex-grow, flex-shrink и flex-basis, которые обычно объединяют в краткую запись flex. Они применяются не к контейнеру, а к каждому flex-элементу в отдельности.

  1. flex-basis: Определяет начальный размер элемента вдоль главной оси до распределения свободного пространства. Аналогично width (для flex-direction: row) или height (для column).
  2. flex-grow: Определяет способность элемента растягиваться, чтобы заполнить доступное пространство в контейнере. Значение по умолчанию 0 (не растягиваться). Если всем элементам задать flex-grow: 1, они поровну поделят свободное место.
  3. flex-shrink: Определяет способность элемента сжиматься, если не хватает места в контейнере. Значение по умолчанию 1 (может сжиматься). 0 запрещает сжатие, что полезно для фиксированных элементов вроде иконок или кнопок.
.box {
  flex: 1 1 200px; /* flex-grow: 1, flex-shrink: 1, flex-basis: 200px */
}
.box-special {
  flex: 3 0 150px; /* Растет в 3 раза быстрее других, не сжимается, начальный размер 150px */
}

Эти свойства становятся супероружием в сочетании с min-width/max-width и медиа-запросами. Например, можно создать адаптивную навигационную панель, где логотип не сжимается, а остальные пункты меню равномерно заполняют пространство.

.nav {
  display: flex;
  align-items: center;
  padding: 1rem;
}
.logo {
  flex-shrink: 0; /* Логотип никогда не сжимается */
  margin-right: auto; /* "Отталкивает" все последующие элементы вправо */
}
.menu-item {
  flex: 0 1 auto; /* Стандартное поведение, может сжиматься, если нужно */
  margin-left: 1rem;
}

Отдельное выравнивание элемента: align-self и практическое применение

Для точечного управления отдельным элементом по поперечной оси в CSS Flexbox существует свойство align-self.

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

.container {
  display: flex;
  align-items: flex-start; /* Все элементы у верхнего края */
}
.box-special {
  align-self: flex-end; /* А этот конкретный элемент — у нижнего края */
}

К сожалению, аналогичного свойства justify-self для главной оси в чистом Flexbox нет (оно работает в CSS Grid). Однако для схожих задач, например, чтобы оттолкнуть один элемент вправо (как логотип в навигации), можно использовать старый добрый трюк с margin-right: auto (или margin-left: auto для правого элемента).

Заключение: Flexbox как фундамент современной верстки

Освоив CSS Flexbox, вы получаете в руки инструмент, который покрывает 90% задач по построению макетов компонентов интерфейса: навигаций, карточек, форм, выравнивания контента. Его логика с осями интуитивно понятна, а комбинации свойств дают безграничные возможности.

Flexbox идеально подходит для одномерных макетов (распределение в строке или колонке). Для более сложных двумерных сеток (одновременное управление и строками, и колонками с точностью до пикселя) следующим логичным шагом будет изучение CSS Grid Layout. Эти две технологии не конкурируют, а прекрасно дополняют друг друга в арсенале профессионального фронтенд-разработчика.

Хотите, чтобы ваш сайт обладал безупречной, современной и молниеносно адаптивной версткой? Наша веб-студия создает цифровые продукты, в основе которых лежат чистый, семантичный код и передовые технологии вроде Flexbox и Grid.

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

Теги: