Flexbox в CSS: flex-grow, flex-shrink, flex-wrap и order

Введение
Современные макеты сайтов должны корректно реагировать на изменение контента и размеров окна браузера. Flexbox — один из самых простых и мощных инструментов для создания адаптивных рядов и колонок. В этой статье мы подробно разберём ключевые свойства: flex-grow, flex-shrink, flex-wrap, flex-flow и order, покажем рабочие примеры и дадим практические рекомендации.
Кому это полезно: фронтенд-разработчикам, верстальщикам и дизайнерам интерфейсов.
Короткие определения
- Flex container — контейнер с display: flex. Он управляет расположением дочерних элементов.
- Flex item — дочерний элемент внутри flex container.
- flex-grow — коэффициент роста элемента при наличии свободного пространства.
- flex-shrink — коэффициент сжатия элемента при нехватке места.
- flex-wrap — разрешение переноса элементов на новую строку/колонку.
- flex-flow — сокращённая запись для flex-direction и flex-wrap.
- order — число, определяющее визуальный порядок элемента.
Как настроить flex-контейнер
Оборачивайте дочерние элементы в родительский div и задавайте ему display: flex.
.parent {
display: flex;
}Это базовая установка. Flex-контейнер по умолчанию располагает элементы в строке (row), не переносит их (nowrap) и выравнивает по началу оси (flex-start).
flex-grow — как заставить элементы «расти»
flex-grow указывает, какую долю свободного пространства возьмёт элемент относительно других. Значение — число (коэффициент). По умолчанию значение 0.
Пример: три элемента получают по 1, а четвёртый — 3.
.parent {
width: 500px;
display: flex;
}Если у всех элементов flex-grow: 0, они сохраняют свою базовую ширину и не заполняют свободное пространство.
Совет: flex-grow учитывает доступное пространство после учёта полей, отступов и фиксированных размеров. Если хотите задать фиксированную минимальную ширину, используйте min-width.
flex-shrink — как контролировать сжатие
flex-shrink задаёт, как элементы уменьшаются при нехватке места. Значение — коэффициент. По умолчанию 1.
Пример, где элементы не умещаются в контейнере, и зелёный элемент сжимается сильнее:
.parent {
width: 500px;
display: flex;
}
.parent div {
width: 150px;
height: 150px;
}Примечание: flex-shrink работает относительно базовой ширины элемента (width) и других flex-значений. Чтобы полностью запретить сжатие, используйте flex-shrink: 0.
flex-wrap — как переносить элементы на новую строку
flex-wrap разрешает перенос элементов, если они не помещаются по основной оси. Значения: nowrap | wrap | wrap-reverse.
.parent {
width: 300px;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
}
.parent div {
width: 100px;
height: 100px;
}wrap разместит строки сверху вниз, а wrap-reverse — в обратном порядке (нижняя строка станет первой визуально).
Если вы задали высоту контейнера, между строками может появиться пространство. Уберите отступы между строками через align-content.
.parent {
width: 300px;
height: 300px;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}align-content управляет распределением свободного пространства между строками (или колонками), когда есть несколько рядов элементов.
flex-flow — сочетание направления и переноса
flex-flow — сокращение для flex-direction и flex-wrap. Удобно, когда нужно одновременно задать направление (row/column) и поведение переноса.
Примеры комбинаций:
/* направления и перенос */
flex-flow: row nowrap;
flex-flow: column wrap;
flex-flow: row wrap-reverse;.parent {
width: 300px;
border: 1px solid black;
display: flex;
flex-flow: column wrap;
}
.parent div {
width: 100px;
height: 100px;
}flex-flow полезен, когда макет должен адаптироваться от строк к колонкам в узких картах интерфейса.
order — визуальный порядок без изменения DOM
Свойство order задаёт целое число. Браузер сортирует элементы по возрастанию order и визуализирует их в этом порядке.
В примере orange будет слева (или в начале строки), затем red, blue, green и yellow. Плюс: вы можете переставлять элементы для различных точек останова (media queries) без изменения HTML.
Важно: order влияет только на визуальный порядок; порядок в DOM остаётся прежним — это важно для доступности и фокусировки клавиатурой.
Частые ошибки и когда flex не подойдёт
- Ожидание, что flex заменит CSS Grid во всех случаях. Grid лучше подходит для двумерных макетов (строки + колонки одновременно).
- Использование order для логики: не меняйте порядок контента, если это ломает смысл или доступность. Для SEO и скринридеров DOM-порядок важен.
- Забыт min-width/min-height: элементы с flex-grow могут «сливаться» при малых размерах экрана. Задавайте min-width чтобы сохранить читабельность.
- Ожидание одинаковой высоты без учета box-sizing, padding и border. Помните, что размеры включают поля и границы, если box-sizing: border-box не задан.
Альтернативы и когда их применять
- CSS Grid — когда нужно управлять как строками, так и колонками одновременно (например, сетка карточек с разными размерами).
- Медиа-запросы — для радикальной перестройки макета на разных экранах (mobile-first). Flex часто комбинируют с медиа-запросами.
- Inline-block / float — устаревшие методы; иногда остаются в старых проектах, но Flex значительно проще и надёжнее.
Ментальные модели и эвристики
- Представьте flex-контейнер как полку, а flex-items — как коробки. flex-grow — коробка растягивается, чтобы занять пустое место. flex-shrink — коробка сжимается, чтобы уместиться. flex-wrap — коробки переходят на следующую полку.
- Думайте в относительных коэффициентах: если у двух элементов flex-grow 1 и 2, второй займёт в два раза больше свободного места.
- Всегда сначала определите базовую ширину/высоту элементов, затем добавляйте flex-правила.
Шпаргалка (cheat sheet)
- display: flex — делает контейнер флекс-контейнером.
- flex-direction: row | column | row-reverse | column-reverse
- flex-wrap: nowrap | wrap | wrap-reverse
- flex-flow:
- justify-content — выравнивание по основной оси
- align-items — выравнивание по поперечной оси для отдельных строк
- align-content — распределение пространства между строками (когда есть несколько строк)
- flex:
— сокращённая запись (часто используется) - order:
— порядок отображения
Пример сокращённой записи:
.child {
flex: 1 1 150px; /* grow shrink basis */
}Ролевые чек-листы
Для разработчика:
- Проверить, что контейнер имеет display: flex.
- Установить min-width/min-height для важных блоков.
- Использовать flex: shorthand для компактности.
- Тестировать на разных разрешениях и с реальным контентом.
Для дизайнера:
- Уточнить, какой элемент должен «расти» или «сжиматься» при изменении пространства.
- Определить, какой порядок важен в мобильной и десктопной версиях.
- Проверить доступность: логика чтения не должна зависеть от order.
Для QA:
- Тестировать поведение при уменьшении и увеличении окна.
- Проверить фокус клавиатурой и последовательность скринридера.
- Проверить отступы между строками при flex-wrap и align-content.
Мини-методология внедрения flex в проект
- Определите контейнеры, где нужен одинерн-изменяемый ряд/колонка.
- Задайте display: flex; определите flex-direction.
- Установите базовый размер (width/height/basis) для детей.
- Добавьте flex-grow / flex-shrink для нужных приоритетов.
- При необходимости используйте flex-wrap/flex-flow.
- Тестируйте на реальных данных и добавьте min/max размеры.
Критерии приёмки
- Макет не ломается при изменении ширины окна между 320px и 1920px.
- Ключевые элементы видимы и доступны (фокус, порядок чтения).
- Визуальный порядок соответствует техническим требованиям без изменения DOM.
- Отступы между строками контролируются через align-content.
Сценарии тестирования и приёмочные критерии
- Уменьшить ширину контейнера: элементы корректно переходят на новую строку при flex-wrap: wrap.
- Установить flex-shrink: 0 на важный блок: блок не сжимается и появляется прокрутка, если место кончилось.
- Поменять order в media query: визуальный порядок меняется, DOM-порядок остаётся прежним.
Заключение
Flexbox — простой и мощный инструмент для однородных макетов в одном измерении. Он позволяет гибко управлять размерами и порядком элементов без сложных вычислений. Для двумерных сеток используйте CSS Grid. Комбинация Flexbox + Grid + медиазапросы даёт высокий уровень контроля над адаптивностью интерфейса.
Важно: сохраняйте семантику в DOM и не полагайтесь только на визуальный порядок, если контент важен для доступности.
Если хотите — приложите пример вашего HTML/CSS, и я помогу адаптировать flex-правила для конкретного макета.