Справочник · CSS
flex: как элемент растёт и сжимается
Свойство flex — сокращённая запись трёх свойств flex-элемента: flex-grow (сколько свободного места забрать), flex-shrink (насколько сжиматься при нехватке места) и flex-basis (стартовый размер). Его задают детям flex-контейнера: flex: 1 делит место поровну, flex: none запрещает растягиваться и сжиматься.
flex: grow shrink basis— три значения в одной записи.flex: 1=1 1 0%: элементы делят место поровну.flex: auto=1 1 auto: растут, но с учётом содержимого.flex: none=0 0 auto: размер по содержимому, без растяжения.- По умолчанию у элементов
0 1 auto: не растут, но сжимаются.
Минимальный пример
.row { display: flex; gap: 16px; }
.row .main { flex: 1; } /* забирает всё свободное место */
.row .aside { flex: 0 0 240px; } /* ровно 240px: не растёт и не сжимается */Боковая колонка держит ширину 240px, а основная занимает всё остальное. Свойство пишут детям контейнера с display: flex — на обычных блоках оно ничего не делает.
Три части свойства
| Часть | По умолчанию | Что задаёт |
|---|---|---|
flex-grow | 0 | доля свободного места, которую элемент забирает; 0 — не растёт |
flex-shrink | 1 | насколько сжимается при нехватке места; 0 — не сжимается |
flex-basis | auto | стартовый размер вдоль главной оси до роста и сжатия |
Браузер сначала ставит каждому элементу размер flex-basis, потом считает остаток места. Если место осталось — раздаёт его по долям flex-grow. Если не хватает — отнимает пропорционально flex-shrink (с учётом размера элементов).
Частые значения
| Запись | grow shrink basis | Поведение |
|---|---|---|
flex: initial | 0 1 auto | значение по умолчанию: не растёт, может сжаться |
flex: 1 | 1 1 0% | равные доли места независимо от содержимого |
flex: 2 | 2 1 0% | вдвое больше доля, чем у flex: 1 |
flex: auto | 1 1 auto | растёт, но больше места получает тот, у кого больше содержимого |
flex: none | 0 0 auto | размер по содержимому, жёстко |
flex: 0 0 240px | 0 0 240px | фиксированный размер 240px |
flex: 1 1 220px | 1 1 220px | стартует с 220px, делит остаток, может сжаться |
flex: 200px | 1 1 200px | одно значение с единицей — это basis |
Важная тонкость: в коротких записях с одним числом базис становится 0%, а не auto. Поэтому flex: 1 делит место ровно поровну, даже если в одном элементе длинный текст, а flex: auto — нет.
flex: 1 или flex: auto
<nav class="tabs">
<a href="#">Обзор</a>
<a href="#">Подробные характеристики</a>
<a href="#">Отзывы</a>
</nav>.tabs { display: flex; }
.tabs a { flex: 1; } /* три вкладки одинаковой ширины */
/* .tabs a { flex: auto; } ширина зависит от длины текста */С flex: 1 все вкладки одинаковой ширины. С flex: auto браузер сначала даёт каждой ширину текста, а остаток делит поровну — «Подробные характеристики» окажется шире. Выбирай по задаче: равные колонки или пропорции по содержимому.
Карточки с переносом
.cards { display: flex; flex-wrap: wrap; gap: 16px; }
.card { flex: 1 1 240px; }Каждая карточка стартует с 240px, делит свободное место поровну и переносится на новую строку, когда места меньше. Две карточки помещаются в ряд, пока ширина контейнера не меньше 2 × 240 + 16 = 496px. На последней строке карточки растянутся шире — если нужны ровные колонки, лучше Grid.
Почему элемент не сжимается
.main { flex: 1; min-width: 0; } /* разрешаем сжиматься меньше содержимого */
.title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }У flex-элемента по умолчанию min-width: auto: он не сожмётся меньше своего содержимого. Длинное слово, URL, таблица или блок pre не дают элементу стать уже, и строка вылезает за контейнер — даже с flex-shrink: 1. Лечится min-width: 0 (или overflow: hidden) на элементе. Для вертикальной оси то же самое делает min-height: 0.
Логотип, который не должен сплющиваться
.header { display: flex; align-items: center; gap: 12px; }
.header .logo { flex: none; } /* не растягивается и не сжимается */
.header .search { flex: 1; min-width: 0; }Иконкам, логотипам и аватарам ставят flex: none или flex-shrink: 0: иначе на узком экране они сплющиваются вместе с соседями.
flex-basis или width
Стартовый размер внутри flex-контейнера вдоль главной оси: работает и для строки, и для колонки, участвует в росте и сжатии.
Обычная ширина. Во flex-строке используется, если basis = auto, но не учитывает смену оси на column.
Частые ошибки
- Пишут
flexэлементу, у родителя которого нетdisplay: flex. - Ждут равных колонок от
flex: auto— нужноflex: 1. - Не ставят
min-width: 0, и длинный текст выталкивает строку за экран. - Не защищают логотип и иконки
flex: none, и они сплющиваются. - Путают порядок значений: первое — grow, второе — shrink, третье — basis.
Доступность
flex меняет размеры, но не порядок чтения. Проверяй, что при увеличении шрифта до 200% элементы не наезжают друг на друга и текст не обрезается без возможности прочитать его целиком. Обрезку через text-overflow: ellipsis применяй только там, где полный текст доступен (подсказка, отдельная страница).
Поддержка браузерами
Свойство flex и его части поддерживаются всеми актуальными браузерами. Префиксы -webkit- для новых проектов не нужны.
Практика
Сделай шапку: логотип слева фиксированного размера, поле поиска посередине, которое занимает всё свободное место и не вылезает на узком экране, и кнопка «Войти» справа по ширине текста. Затем сделай три вкладки одинаковой ширины.
Показать решение
.header { display: flex; align-items: center; gap: 12px; }
.header .logo { flex: none; }
.header .search { flex: 1; min-width: 0; }
.header .login { flex: none; }
.tabs { display: flex; }
.tabs a { flex: 1; text-align: center; }Частые вопросы
Что значит flex: 1?
flex-grow: 1; flex-shrink: 1; flex-basis: 0%. Элементы с flex: 1 делят свободное место поровну независимо от содержимого.
Чем flex: 1 отличается от flex: auto?
flex: 1 начинает с нулевого базиса и делит место поровну. flex: auto начинает с размера содержимого, поэтому элементы с длинным текстом получаются шире.
Почему flex-элемент не сжимается?
По умолчанию у него min-width: auto — он не становится уже содержимого. Добавь min-width: 0.
Как сделать элемент фиксированной ширины во flex?
flex: 0 0 240px — не растёт, не сжимается, ширина 240px.
Какое значение flex по умолчанию?
0 1 auto: элемент не растёт, может сжиматься, стартовый размер — по width или содержимому.