
🔍 Мистический inline-flex: что это и чем отличается от display: flex
Что такое display: inline-flex
Flexbox плотно вошёл в повседневную вёрстку. display: flex знают и применяют все фронтендеры. Но у этого свойства есть менее известный двойник, display: inline-flex. Про него пишут редко, а используют ещё реже. И зря.
Разница сводится к одному предложению: inline-flex создаёт flex-контейнер, который сам ведёт себя как строчный элемент. Потомки внутри него: обычные flex-элементы со всеми возможностями Flexbox. А вот родитель не занимает всю доступную ширину строки. Он подстраивается под размер содержимого и встаёт в один ряд с соседними элементами.

Ситуация точь-в-точь как с парой display: block и display: inline-block. Блочный элемент забирает строку целиком, строчный: только сколько нужно контенту. Так и здесь: flex задаёт блочный flex-контейнер, а inline-flex задаёт строчный.
На практике это открывает сценарии, которые с обычным flex потребовали бы лишних обёрток, хаков с шириной или float-пережитков.
💡 Быстрый обзор:
display: inline-flexзадаёт flex-контейнер, который ведёт себя как строчный элемент и не занимает всю строку целиком. Ширина такого контейнера определяется содержимым, а не родителем.- Все flex-свойства работают внутри
inline-flexточно так же, как в обычномdisplay: flex. Никаких отличий в раскладке потомков нет, разница только во внешнем поведении контейнера. - Основной юзкейс: бейджи, теги и кнопки с иконками, где один
inline-flexна элементе заменяет связку flex-родителя и строчного потомка. Вы получаете центрирование содержимого без лишних обёрток. - У других display-значений тоже есть инлайн-аналоги:
inline-block,inline-tableиinline-gridработают по тому же принципу. Внутренняя логика раскладки сохраняется, меняется только внешнее поведение контейнера.
Реальный кейс: бейджи с иконками
Представьте типовую задачу. На странице нужен ряд бейджей. У каждого, иконка и текст, причём иконка отцентрирована по вертикали и горизонтали внутри цветного кружка. Сами бейджи стоят в строку, как обычный текст, и переносятся на следующую строку, когда не помещаются.

Если поставить бейджам display: flex, каждый из них растянется на всю ширину родителя. Бейджи выстроятся в колонку, а не в строку. Исправить это можно обёрткой с display: flex на родителе. Но зачем лишний враппер, если есть inline-flex?
HTML-структура элементарная:
1 <div class="badges-list"> 2 <span class="c-badge"> 3 <svg class="c-icon" width="24" height="24">...</svg> 4 </span> 5 <span class="c-badge"> 6 <svg class="c-icon" width="24" height="24">...</svg> 7 </span> 8 <!-- остальные бейджи --> 9 </div>
Обратите внимание: враппер .badges-list не делает ничего для инлайнового позиционирования. За это отвечает сам .c-badge.
CSS для бейджа:
1 .c-badge { 2 display: inline-flex; 3 justify-content: center; 4 align-items: center; 5 }
Всё. Каждый бейдж, flex-контейнер со строчным поведением. Иконка внутри центрируется с помощью justify-content и align-items. Сами бейджи выстраиваются в строку и переносятся на новую, если не хватает ширины. Ровно то, что требовалось по дизайну, без лишних обёрток.
inline-flex vs flex: наглядное сравнение
Лучший способ понять разницу, посмотреть на два одинаковых набора контейнеров, один с display: flex, второй с display: inline-flex.
Пример 1: display: flex
Три родительских контейнера с синим фоном. Внутри каждого, три красных потомка с flex: 1. Родителям задан display: flex.
Результат: каждый синий контейнер занимает всю строку. Потомки внутри растягиваются на равную ширину. Контейнеры выстроились в колонку, друг под другом.
1 .container--flex { 2 display: flex; 3 } 4 5 .container--flex > div { 6 flex: 1; 7 }

Пример 2: display: inline-flex
Те же три контейнера, но с display: inline-flex. Потомкам добавлен min-width: 50px, чтобы контейнер не схлопнулся в ноль.
1 .container--inline-flex { 2 display: inline-flex; 3 } 4 5 .container--inline-flex > div { 6 flex: 1; 7 min-width: 50px; 8 }
Результат: контейнеры встали в один ряд. Каждый занимает ровно столько ширины, сколько нужно потомкам (50px × 3 = 150px). Они ведут себя как слова в предложении, переносятся на следующую строку, только когда заканчивается место.

Ключевой вывод: для flex-элементов внутри контейнера разницы нет вообще. Свойства вроде justify-content и align-items, а также gap и flex-direction работают идентично. Разница только в том, как сам контейнер взаимодействует с внешним миром. Как блок, или как строка.
Когда стоит применять inline-flex: 4 сценария
Не каждый макет требует inline-flex. Но есть ситуации, где он решает задачу элегантнее, чем комбинация flex + обёртка.
1. Список тегов или бейджей. Самое частое применение. Каждый тег, flex-контейнер, внутри которого иконка и текст выровнены по центру. Сами теги идут в строку с переносом. inline-flex на теге, и никаких врапперов.
2. Кнопки с иконкой в строке текста. Когда кнопка-действие (скопировать, открыть, удалить) стоит прямо внутри абзаца или заголовка. inline-flex позволяет отцентрировать иконку внутри кнопки, не вырывая кнопку из текстового потока.
3. Инлайн-панель инструментов. Набор кнопок форматирования в WYSIWYG-редакторе. Каждая кнопка, inline-flex-контейнер с иконкой внутри. Все кнопки стоят в строку и переносятся естественным образом.
4. Вертикальное центрирование в строчном контексте. Классическая CSS-боль: отцентрировать иконку по вертикали относительно соседнего текста. vertical-align: middle работает через раз. inline-flex с align-items: center, работает всегда.
Приведу код для сценариев 2 и 3, чтобы не оставлять их на уровне теории.
Кнопка с иконкой в тексте (сценарий 2). Допустим, внутри абзаца нужна кнопка «скопировать». Она обязана остаться в текстовом потоке и не сломать строку. Вот минимальный CSS:
1 .inline-action-btn { 2 display: inline-flex; 3 align-items: center; 4 justify-content: center; 5 width: 24px; 6 height: 24px; 7 border: none; 8 background: transparent; 9 cursor: pointer; 10 vertical-align: middle; 11 }
Три строчки flexbox-центрирования, и иконка внутри кнопки выровнена по обеим осям. Никаких line-height-хаков, никаких position: relative плюс transform. Кнопка сидит прямо в тексте, как ещё одно слово.
Панель инструментов (сценарий 3). Типичный WYSIWYG-редактор: кнопки «жирный», «курсив», «ссылка» стоят в строку. Каждая кнопка, это inline-flex-контейнер:
1 .toolbar__btn { 2 display: inline-flex; 3 align-items: center; 4 justify-content: center; 5 width: 32px; 6 height: 32px; 7 border-radius: 4px; 8 }
Кнопки переносятся при сужении окна без дополнительных врапперов. Для родительской панели подойдёт display: flex с flex-wrap: wrap и gap: 4px. Получается двухуровневая flex-композиция: внешний контейнер управляет строкой кнопок, а каждая кнопка центрирует свою иконку.
Подводные камни inline-flex
Три неочевидные ситуации, которые экономят часы в DevTools.
Пробелы между элементами. Как и inline-block, элементы с inline-flex чувствительны к пробелам в HTML. Три <span> с inline-flex на отдельных строках получат зазор в 4-5 пикселей. Лечится: font-size: 0 на родителе с восстановлением на потомках, удаление пробелов между тегами или связка display: flex на родителе плюс inline-flex на потомках.
text-align не работает на flex-потомках. Для inline-block элементы выравнивают через text-align: center на родителе. С inline-flex этот приём работает, только пока потомки не стали flex-контейнерами. Flex-элементы не реагируют на text-align. Выравнивайте контейнеры через justify-content на flex-родителе или margin: auto.
Flex-направление по умолчанию. inline-flex, как и display: flex, по умолчанию раскладывает потомков в строку (flex-direction: row). Ожидаете колонку внутри строчного контейнера, задавайте flex-direction: column явно. Спецификация не читает мысли верстальщика.

Родственники: другие инлайн-варианты display
У inline-flex есть идейные собратья. Почти каждое блочное значение display имеет строчный аналог:
Блочное значение | Строчный аналог |
|---|---|
|
|
|
|
|
|
|
|
Механика везде одинаковая: внутренняя логика раскладки сохраняется полностью, меняется только внешнее поведение контейнера. С inline-grid история та же, грид-контейнер, который встаёт в строку, а не на всю ширину родителя.
На практике inline-flex используют чаще inline-grid. Причина простая: flex-контейнеры чаще нужны для мелких компонентов (бейдж, кнопка, группа иконок), где строчное поведение, как раз то, что нужно. Грид-раскладку чаще применяют к крупным структурным блокам, которым inline-поведение ни к чему.
Браузерная поддержка у inline-flex практически полная. Свойство появилось в спецификации Flexible Box Layout Module Level 1 (кандидат в рекомендации W3C, 2016 год) и работает во всех современных браузерах: Chrome с 29-й версии (2013), Firefox с 20-й (2013), Safari с 9-й (2015), Edge с 12-й (2015). Internet Explorer 11 поддерживает inline-flex с оговорками, но по данным StatCounter на 2025 год доля IE11 составляет менее 0.1% мирового рынка. Для проектов которые обязаны поддерживать IE11, inline-flex проверяйте вручную: в части багов с flex-basis и min-height этот браузер ведёт себя непредсказуемо.
⁉️🤔 Частые вопросы
В чём разница между display: inline-flex и display: flex?
display: flexсоздаёт блочный flex-контейнер, он занимает всю доступную ширину строки.display: inline-flexсоздаёт строчный flex-контейнер, его ширина определяется содержимым, и он может стоять в одной строке с другими элементами. Для потомков внутри контейнера разницы нет: все flex-свойства работают одинаково в обоих случаях.
Когда inline-flex лучше, чем inline-block?
inline-blockне даёт контроля над выравниванием потомков. Если нужно отцентрировать иконку внутри кнопки по вертикали и горизонтали,inline-blockзаставит вас вспоминатьline-height-хаки иvertical-align.inline-flexсjustify-content: centerиalign-items: centerделает это без танцев с бубном.
Можно ли использовать gap с inline-flex?
Да,
gapработает вinline-flexточно так же, как в обычномflex. Вы задаёте промежуток между flex-элементами, и браузер применяет его независимо от того, блочный контейнер или строчный. Поддержкаgapво flexbox, все современные браузеры с 2021 года.
Влияет ли inline-flex на вложенные flex-контейнеры?
Нет. Свойство
displayне наследуется. Если внутриinline-flex-контейнера лежит элемент сdisplay: flex, он будет обычным блочным flex-контейнером. Строчное поведение касается только того элемента, которому вы явно задалиinline-flex.
*inline-flex** и доступность, есть ли подводные камни?*
Скринридеры не делают различий между
flexиinline-flex. Оба значения влияют только на визуальную раскладку и не меняют семантику или порядок чтения. Flex-свойствоorderменяет визуальный порядок, но не порядок в accessibility tree, это верно для обоих значенийdisplay.
Что ставить: flex или inline-flex
Выбор сводится к простому вопросу: контейнер должен стоять в строку с соседями или занять всю ширину родителя?
Если вёрстка компонента, бейдж, кнопка с иконкой, тег, элемент тулбара, ставьте inline-flex. Вы получите flex-центрирование содержимого и сохраните естественное строчное поведение без дополнительных обёрток.
Если вёрстка секции, карточки, шапки, футера или лейаута, оставляйте display: flex. Блочное поведение здесь уместно: контейнер должен занять свою строку, а не вклиниваться между соседними элементами.
Золотое правило: идёте в DevTools, смотрите на элемент. Если он в строке с другими, inline-flex. Если он на своей строке, flex. Проще некуда.



