Блокові, інлайнові та інлайново-блокові елементи в HTML та CSS
display: block, display: inline та display: inline-block визначають, як елементи займають місце і рухаються в потоці документа.
Теорія
Коротко
- Block - як оголошення на всю сторінку: займає весь рядок, стекується вертикально, поважає всі box model властивості.
- Inline - як слово в реченні: тече горизонтально, ігнорує
width/height, працюють тільки ліві та праві margin. - Inline-block - як зображення в тексті: тече в рядку, але поважає
width,heightі всі margin. - Головна різниця: block примушує перенос рядка і повну ширину; inline ігнорує розміри; inline-block дозволяє і те, і інше.
- Правило вибору: block для секцій layout, inline для стилізації тексту, inline-block для кнопок або іконок в рядку.
Швидкий приклад
<style>
.block { display: block; background: lightblue; padding: 10px; margin: 10px; }
.inline { display: inline; background: lightgreen; padding: 10px; margin: 10px; }
.inl-block { display: inline-block; background: lightcoral; padding: 10px; margin: 10px; width: 120px; height: 50px; }
</style>
<!-- Стекується вертикально, повна ширина -->
<div class="block">Block 1</div>
<div class="block">Block 2 (нижче)</div>
<!-- Розташовується поряд, ігнорує width/height -->
<span class="inline">Inline 1</span>
<span class="inline">Inline 2</span>
<!-- Розташовується поряд, поважає розміри -->
<span class="inl-block">Inline-block 1</span>
<span class="inl-block">Inline-block 2</span>Block-елементи стекуються. Inline-елементи стоять поряд, але не приймають width чи height. Inline-block стоїть поряд і приймає розміри.
Ключова різниця
Block примушує перенос рядка до і після себе, а потім розтягується на всю ширину контейнера. Саме тому <div> займає весь рядок навіть якщо в ньому одне слово. Inline вливається в текстовий потік, як слово в реченні: без переносу рядка, без реакції на width чи height. Inline-block - середній варіант. Лишається в потоці рядка, але створює блок з розмірами. Тому кнопки зазвичай так і роблять.
Коли що використовувати
- Потрібно стекувати вертикально і заповнити ширину? Block. Секції, заголовки, контейнери статей.
- Стилізуєш частину речення або обертаєш посилання всередині тексту? Inline.
<span>,<a>,<em>. - Кнопка, бейдж або таб навігації з padding і розміром, які мають стояти поряд? Inline-block.
- Не встановлюй
widthчиheightна inline-елементи - вони не матимуть ефекту.
Таблиця порівняння
| Властивість | block | inline | inline-block |
|---|---|---|---|
| Новий рядок | Так | Ні | Ні |
width / height | Так | Ні | Так |
| Margin (всі сторони) | Так | Тільки ліво/право | Так |
| Padding (всі сторони) | Так | Тільки ліво/право | Так |
| Повна ширина за замовчуванням | Так | Ні | Ні |
| Коли використовувати | Секції, контейнери | Стилізація тексту | Кнопки, бейджі, таби |
Типові помилки
Встановлення width/height на inline-елементи:
span { display: inline; width: 200px; height: 100px; } /* обидва ігноруються */Браузер ігнорує ці властивості для inline-елементів. Якщо потрібен розмір - переключи на inline-block.
Очікування вертикальних margin на inline-елементах:
<span style="margin-top: 20px;">Текст</span>Вертикальні margin на inline-елементах не впливають на layout. Працюють тільки margin-left і margin-right. Використовуй inline-block або додай vertical-align.
Пробіл між inline-block елементами:
<span style="display: inline-block; width: 100px;">A</span>
<span style="display: inline-block; width: 100px;">B</span>Перенос рядка між тегами рендериться як ~4px пробіл. Я бачив, як це руйнувало nav-меню не один раз. Виправлення: встановити font-size: 0 на батьківський елемент, або прибрати весь пробіл між закриваючим і відкриваючим тегами.
Де зустрічається в реальних проєктах
- Bootstrap
btn-groupвикористовуєinline-blockдля кнопок в рядку (v5.3+). - Таби навігації GitHub - це
inline-block-посилання з padding і бордерами. - Утиліта
inline-blockв Tailwind з'являється в компонентах кнопок і бейджів. - Компонент Chip у Material UI за замовчуванням використовує
inline-flex- для потоку поводиться так само.
Питання на співбесіді
Q: Яке значення display за замовчуванням у <img>?
A: Inline. Зображення - це замінені елементи (replaced elements), які течуть як текстові символи, але зберігають власні розміри. Тому під зображеннями всередині контейнерів часто є невеликий пробіл - це вирівнювання по базовій лінії, а не баг.
Q: Що відбувається з inline-block дочірніми елементами всередині flex-контейнера?
A: Flex formatting context бере верх. display: flex на батьківському елементі перевизначає inline-потік дочірніх елементів. Але width і height, які ти задав на дочірніх елементах, продовжують працювати.
Q: Чому vertical-align працює тільки для inline і inline-block?
A: Вона вирівнює елементи в межах рядкових боксів (line boxes). Block-елементи створюють власні рядки і не мають line box для вирівнювання.
Q: (Senior) Якщо встановити display: block на grid-елемент, чи вплине це на grid layout?
A: Ні. Grid-елементи ігнорують власну властивість display для позиціювання, бо grid formatting context бере верх. Але зміна впливає на внутрішній контекст форматування: дочірні елементи цього grid-айтема тепер течуть як block. Якщо згадати концепцію containing block - інтерв'юер це помітить.
Приклади
Навігаційна панель з inline-block табами
<nav style="background: #f6f8fa; padding: 1rem;">
<a href="#" style="display: inline-block; padding: 0.5rem 1rem; margin-right: 0.5rem;
background: white; border: 1px solid #ddd; text-decoration: none;">Code</a>
<a href="#" style="display: inline-block; padding: 0.5rem 1rem; margin-right: 0.5rem;
background: white; border: 1px solid #ddd; text-decoration: none;">Issues</a>
<a href="#" style="display: inline-block; padding: 0.5rem 1rem;
background: white; border: 1px solid #ddd; text-decoration: none;">Pull requests</a>
</nav>Кожне посилання потребує padding і бордер, але всі мають стояти в одному рядку. Чистий inline ігноруватиме padding у layout; block поставить кожне посилання на окремий рядок. inline-block дає кожному посиланню правильний блок з розміром і водночас тримає їх поряд. Цей патерн - основа навігації GitHub.
Аватар користувача з іменем
<style>
.avatar-wrap {
display: inline-block;
vertical-align: middle;
margin-right: 8px;
}
.avatar-wrap img {
display: block;
width: 32px;
height: 32px;
border-radius: 50%;
}
.username {
display: inline;
font-weight: bold;
}
</style>
<span class="avatar-wrap">
<img src="avatar.png" alt="Аватар користувача">
</span>
<span class="username">john_doe</span>Обгортка зображення - inline-block, щоб мати фіксований розмір і vertical-align: middle для вирівнювання з текстом поряд. Ім'я користувача - звичайний inline, бо розміри йому не потрібні, воно просто тече як текст.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.