CSS display: block, inline, inline-block и другие значения — понятное практическое руководство
Свойство display определяет, как элемент участвует в потоках документа и рендерится: занимает ли всю строку, можно ли задавать ему ширину и высоту, как считаются отступы и выравнивание. Вопрос «CSS display: block, inline, inline-block — в чём разница?» регулярно задают на собеседованиях и он критичен для грамотной вёрстки.
Что делает display и какие значения бывают
Ключевые значения для базовой вёрстки:
- block — блочный элемент, занимает всю доступную ширину, переносится с новой строки, можно задавать width/height, margin/padding со всех сторон работают ожидаемо.
- inline — строчный, идёт в тексте, ширину/высоту задавать нельзя (игнорируются), вертикальные отступы часто не влияют на поток, а горизонтальные работают.
- inline-block — как строчный (в одной строке с текстом), но можно задавать размеры и все отступы; ведёт себя как «мини-блок в строке».
- none — элемент не отображается и не занимает место в потоке.
- flow-root — создаёт новый корневой форматирующий контекст (полезно для изоляции float и clearfix без хаков).
- contents — «растворяет» сам контейнер, оставляя его детей в потоке, будто родителя нет (осторожно с доступностью).
- list-item — элемент списка с маркером как у li.
- table, table-row, table-cell — табличные модели без реального table-тега.
Примечание: такие значения как flex и grid — отдельные большие темы. Здесь мы их упоминаем лишь для контекста.
CSS display: block, inline, inline-block — в чём разница на практике
Посмотрим на простой пример.
<style>
.demo * { outline: 1px dashed #aaa; }
.block { display: block; background: #f1f5f9; margin: 8px 0; }
.inline { display: inline; background: #fee2e2; margin: 8px; }
.inline-block { display: inline-block; background: #dcfce7; margin: 8px; width: 140px; height: 40px; }
.container { background: #fff; padding: 8px; }
</style>
<div class="demo container">
<div class="block">block — занимает всю строку</div>
Текст до <span class="inline">inline — в потоке текста</span> текст после.
<span class="inline-block">inline-block — можно width/height</span>
<span class="inline-block">ещё один</span>
</div>
- block переносится на новую строку и растягивается на всю ширину родителя по умолчанию;
- inline сидит в тексте: width/height не работают, вертикальные margin часто игнорируются в потоке, padding влияет на фон и кликабельную область, но не выталкивает строку как блок;
- inline-block можно выстроить рядом, задать точные размеры, отступы работают предсказуемо.
Отступы, размеры и базовая линия
Важная деталь: строчные элементы выравниваются по базовой линии текста. Отсюда «просветы» снизу у картинок и inline-block-блоков.
<style>
.card { display: inline-block; width: 120px; height: 60px; background: #e0f2fe; margin: 4px; }
.baseline-demo { background: #fde68a; font-size: 16px; }
.baseline-demo .card { vertical-align: top; } /* убираем «проседание» по базовой линии */
</style>
<p class="baseline-demo">
<span class="card">A</span>
<span class="card">B</span>
<span class="card">C</span>
</p>
Совет: чтобы убрать «просвет» под картинкой внутри текста, используйте vertical-align: middle/top или переводите картинку в display: block, если она не должна идти в тексте.
replaced-элементы: почему img и input «как будто inline-block»
Картинки и некоторые элементы форм — заменяемые (replaced). Даже при display: inline они обладают интринзик‑размерами, поэтому ведут себя ближе к inline-block: учитывают width/height и не ломают поток текста.
display: none против visibility: hidden
- display: none убирает элемент из потока: место не резервируется, скринридеры чаще игнорируют содержимое (зависит от контекста).
- visibility: hidden оставляет место, но делает элемент невидимым. Полезно для измерений или анимаций появления.
<style>
.box { width: 120px; height: 40px; background:#d1fae5; margin:4px 0; }
.none { display:none; }
.hidden { visibility:hidden; }
</style>
<div class="box">Нормально</div>
<div class="box none">display:none (места нет)</div>
<div class="box hidden">visibility:hidden (место осталось)</div>
<div class="box">Следующий</div>
flow-root: чистый clearfix без хака
flow-root создаёт новый форматирующий контекст, изолируя float и внутренние потоки. Раньше это решали overflow: hidden или clearfix-хаком.
<style>
.wrap { background:#eef2ff; margin:8px 0; }
.float { float:left; width:120px; height:60px; background:#c7d2fe; margin:8px; }
.clearfix-hack { overflow:hidden; }
.flow-root { display: flow-root; }
</style>
<div class="wrap clearfix-hack">
<div class="float">float</div>Контент возле float (clearfix через overflow)
</div>
<div class="wrap flow-root">
<div class="float">float</div>Контент возле float (display:flow-root)
</div>
Совет: используйте flow-root для локального «сброса» влияния float и управления контекстом форматирования без побочных эффектов overflow.
contents: когда нужен, а когда нет
display: contents убирает сам контейнер на уровне рендера, но его дети остаются. Это удобно для семантической обёртки без влияния на layout. Однако некоторые браузерные фичи (например, доступность, transform, z-index) могут работать не так, как ожидается.
<style>
.grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.faux-wrapper { display: contents; }
.item { background:#faf5ff; padding:8px; }
</style>
<div class="grid">
<div class="faux-wrapper">
<div class="item">A</div>
<div class="item">B</div>
</div>
<div class="item">C</div>
</div>
Если вам нужно именно визуально убрать родителя, но оставить его как цель для aria-label, transform и т. п., contents может не подойти.
list-item и кастомные маркеры
Любому элементу можно задать поведение списка.
<style>
.feature { display:list-item; list-style: square inside; margin:4px 0; }
</style>
<div class="feature">Пункт без <code>li</code></div>
<div class="feature">Можно задать собственный маркер</div>
Типичные ошибки и как их избежать
- Пытаться задать width/height строчным элементам (inline) — они игнорируются. Переключите на inline-block или block.
- «Просвет» между inline-block-элементами из‑за пробелов в HTML. Решения: убрать пробелы, задать font-size:0 родителю, или использовать flex/grid для раскладки.
- Неожиданные вертикальные отступы у inline: top/bottom margin часто не влияют на поток. Используйте padding или переводите в блочную модель.
- display: none для скрытия контента, который нужен скринридерам. Рассмотрите visually-hidden техники или aria-атрибуты в зависимости от задачи.
Когда какой display выбирать
- block: секции, карточки, контейнеры, где нужна ширина и вертикальные отступы.
- inline: ссылки в тексте, акценты, короткие иконки внутри строки.
- inline-block: бейджи, кнопки, иконки с текстом, элементы, которые должны стоять «в ряд», но с фиксированными размерами.
- flow-root: изоляция float и внутренних контекстов без overflow-хаков.
- contents: убрать визуальное влияние обёртки, но оставить её детей (помня о нюансах доступности).
- list-item: нестандартные элементы списков с маркерами, когда li неуместен семантически.
Мини‑практикум
- Сделайте навигацию из ссылок, расположенных в одну строку, с равными горизонтальными отступами. Выберите между inline и inline-block и объясните почему.
- Сверстайте маленькие карточки‑бейджи с фиксированной шириной в одну строку и выровняйте их по верхнему краю (подсказка: inline-block + vertical-align: top).
- Превратите div в пункт списка с квадратным маркером через display: list-item и list-style.
Хотите быстрее и увереннее разбираться в таких нюансах вёрстки? Загляните в практический курс: Прокачать вёрстку на «Вёрстка сайта с нуля 2.0» — много практики, разборы ошибок и современные приёмы.
Итоги
Теперь вы знаете, в чём разница между CSS display: block, inline, inline-block, как работают flow-root, contents и list-item, и какие подводные камни встречаются чаще всего. Правильный выбор display делает макет предсказуемым, а код — чище и проще для поддержки.
-
Создано 22.04.2026 17:01:12
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.