</> Praktum

Главная / CSS / Свойство flex

Справочник · CSS

flex: как элемент растёт и сжимается

Редакция PraktumОбновлено 6 мин чтенияУровень: новичок

Свойство 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
ЧастьПо умолчаниюЧто задаёт
flex-grow0доля свободного места, которую элемент забирает; 0 — не растёт
flex-shrink1насколько сжимается при нехватке места; 0 — не сжимается
flex-basisautoстартовый размер вдоль главной оси до роста и сжатия

Браузер сначала ставит каждому элементу размер flex-basis, потом считает остаток места. Если место осталось — раздаёт его по долям flex-grow. Если не хватает — отнимает пропорционально flex-shrink (с учётом размера элементов).

Частые значения

Что раскрывается из короткой записи
Записьgrow shrink basisПоведение
flex: initial0 1 autoзначение по умолчанию: не растёт, может сжаться
flex: 11 1 0%равные доли места независимо от содержимого
flex: 22 1 0%вдвое больше доля, чем у flex: 1
flex: auto1 1 autoрастёт, но больше места получает тот, у кого больше содержимого
flex: none0 0 autoразмер по содержимому, жёстко
flex: 0 0 240px0 0 240pxфиксированный размер 240px
flex: 1 1 220px1 1 220pxстартует с 220px, делит остаток, может сжаться
flex: 200px1 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-basis

Стартовый размер внутри flex-контейнера вдоль главной оси: работает и для строки, и для колонки, участвует в росте и сжатии.

width

Обычная ширина. Во 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 или содержимому.

Источники

Ещё в разделе CSS