Skip to content

Всё для WordPress, веб-разработки — и не только

🔍 Мистический inline-flex: что это и чем отличается от display: flex

🔍 Мистический inline-flex: что это и чем отличается от display: flex

Что такое display: inline-flex

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

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

Свойство inline-flex в панели DevTools браузера

Ситуация точь-в-точь как с парой 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}
Три flex-контейнера друг под другом, каждый на своей строке

Пример 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). Они ведут себя как слова в предложении, переносятся на следующую строку, только когда заканчивается место.

Три inline-flex контейнера в один ряд со строчным поведением

Ключевой вывод: для 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 явно. Спецификация не читает мысли верстальщика.

Ноутбук с HTML-кодом на экране, работа фронтенд-разработчика

Родственники: другие инлайн-варианты display

У inline-flex есть идейные собратья. Почти каждое блочное значение display имеет строчный аналог:

Блочное значение

Строчный аналог

block

inline-block

flex

inline-flex

grid

inline-grid

table

inline-table

Механика везде одинаковая: внутренняя логика раскладки сохраняется полностью, меняется только внешнее поведение контейнера. С 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. Проще некуда.