Властивість рендеринг CSS
CSS display - властивість, яка визначає як елемент бере участь у розмітці сторінки: блок, inline-бокс, flex/grid контейнер або нічого.
Теорія
TL;DR
blockзаймає весь рядок: новий рядок, повна ширина батьківського контейнера, розміри задаютьсяinlineтече всередині тексту: без переносу рядка, ігнорує явніwidthтаheightinline-blockрозміщується inline, але приймає розміри (ідеально для кнопок і бейджів)flexіgridперетворюють елемент на контейнер компонування для дочірніх елементівnoneповністю виключає елемент з розмітки, місце не резервується
Швидкий приклад
<style>
.block { display: block; background: #bcd; margin: 4px 0; }
.inline { display: inline; background: #bdc; }
.iblock { display: inline-block; background: #dbc; width: 120px; height: 40px; }
</style>
<div class="block">Block: займає всю ширину, новий рядок</div>
<div class="block">Block: другий стає нижче</div>
<span class="inline">Inline: тече</span>
<span class="inline">поруч з іншими</span>
<span class="iblock">inline-block</span>
<span class="iblock">враховує розміри</span>Блоки складаються вертикально і заповнюють контейнер. Inline-елементи йдуть один за одним і ігнорують задані розміри. inline-block поєднує обидва підходи: тече inline, але приймає width і height.
Головна різниця: block і inline
Браузер обчислює display під час каскадування, а потім на етапі layout будує дерево боксів. block створює блоковий бокс з новим блоковим контекстом форматування: повна ширина, вертикальне складання. inline створює inline-бокси, що течуть горизонтально всередині рядкового боксу. Практичний наслідок: задати width або height для чистого inline-елемента і очікувати результату - марна справа. Властивості просто ігноруються.
Коли що використовувати
- Секції, заголовки, картки, навбари ->
block - Виділення тексту (
<strong>,<em>), іконки всередині речення ->inline - Кнопки, бейджі, мініатюри з контрольованими розмірами ->
inline-block - Однісне вирівнювання: рядок кнопок, колонка посилань ->
flex - Двовимірні макети: дашборди, шаблони сторінок, сітки ->
grid - Приховати модальне вікно, згорнути блок помилки ->
none
Таблиця порівняння
| Значення | Тип боксу | Ширина/Висота | Перенос рядка | Коли використовувати |
|---|---|---|---|---|
block | Блоковий бокс | Повна ширина батька | Так | Секції, картки, навбари |
inline | Inline-бокс | За контентом | Ні | Текстові spans, іконки в тексті |
inline-block | Inline-block | Задається явно | Ні | Кнопки, поля форм |
flex | Flex-контейнер | Гнучка | Так | Рядкові/колонкові макети |
grid | Grid-контейнер | За сіткою | Так | 2D макети, дашборди |
none | Немає боксу | Немає | Н/Д | Приховання елементів |
Як браузер обробляє display
CSS-рушій (Blink, WebKit) читає display під час каскадування, потім на етапі layout будує дерево боксів. block запускає блоковий контекст форматування. flex активує flex-алгоритм: він збирає дочірні елементи як flex items і розподіляє вільний простір через justify-content та align-items. Зміна display у JavaScript скасовує layout і запускає повний reflow. none найдешевший варіант: браузер пропускає все піддерево, жодного боксу не створюється.
Із досвіду: перемикання display на великому компоненті всередині scroll-контейнера помітно впливає на плавність. visibility: hidden або opacity: 0 дешевші, коли потрібно лише приховати без видалення з потоку.
Типові помилки
Помилка 1: очікувати анімацію при display: none.
/* Неправильно - transition не спрацює */
.modal { display: none; transition: opacity 0.3s; }
/* Правильно */
.modal { opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; }
.modal.open { opacity: 1; visibility: visible; }display: none видаляє елемент миттєво. Проміжного стану немає, тому transition не може відпрацювати. Для ефекту fade використовуй opacity разом з visibility.
Помилка 2: зсув baseline в inline-block.
/* Неправильно - картки вирівнюються по baseline і скачуть */
.card { display: inline-block; }
/* Правильно */
.card { display: inline-block; vertical-align: top; }inline-block за замовчуванням вирівнюється по baseline тексту. Якщо картки різної висоти, вони збиваються в різних напрямках. vertical-align: top виправляє це.
Помилка 3: display: flex на <ul> без скидання стилів списку.
/* Неправильно - маркери вилазять за межі flex-контейнера */
ul { display: flex; }
/* Правильно */
ul { display: flex; list-style: none; padding: 0; margin: 0; }Помилка 4: display: contents на flex item.
display: contents змушує елемент діяти без боксу: його дочірні елементи стають прямими учасниками батьківського layout. Якщо застосувати до flex item з розрахунком, що він займатиме місце, він зникне з flex-потоку. Загортай у <div>, якщо потрібен бокс.
Де зустрічається
- React:
display: isOpen ? 'flex' : 'none'у компонентах Sidebar і Drawer (патерни Material-UI, Chakra UI) - Tailwind CSS: утиліти
hidden,block,inline-block,flex,grid - Bootstrap:
d-none,d-flex,d-blockдля адаптивної видимості - styled-components / CSS Modules:
display: gridдля дашбордів,display: flexдля навігаційних барів
Питання на співбесіді
Q: Яка різниця між display: none і visibility: hidden?
A: none повністю видаляє елемент з потоку, сусідні елементи займають його місце. hidden приховує візуально, але резервує простір. Використовуй hidden, коли зсув layout зламає дизайн.
Q: Чому vertical-align не працює на блочних елементах?
A: vertical-align діє тільки на inline і inline-block бокси. Блочні елементи не беруть участі в inline-контексті форматування, тому властивість ігнорується.
Q: Коли корисний display: contents?
A: Коли є семантична обгортка (наприклад <li> у flex-навігації), яку не хочеш переривати flex-потік. Бокс обгортки зникає, але її діти стають прямими flex items. Обережно: є відомі проблеми з доступністю в деяких браузерах.
Q: flex чи grid - як обрати?
A: flex для однієї осі: рядок кнопок, колонка посилань. grid для двох осей одночасно: повний layout сторінки, фотогалерея з фіксованими рядками і колонками. Вони вільно вкладаються одне в одне.
Q (рівень senior): У flex-контейнері з flex-direction: column чому align-items: stretch розтягує дітей на повну ширину, але margin: auto на дочірньому елементі центрує його горизонтально?
A: align-items: stretch розширює розмір по поперечній осі до того, як вирішуються відступи. margin: auto поглинає весь вільний простір, що залишився після того, як flex-алгоритм визначив розміри. Специфікація вирішує фіксовані розміри спочатку, потім auto-відступи. Тому елемент розтягується через stretch, але auto-відступ перевизначає вирівнювання, поглинаючи залишковий простір.
Приклади
Block і inline поруч
<!DOCTYPE html>
<html>
<head>
<style>
.container { border: 2px solid #333; padding: 10px; }
.block { display: block; background: #adf; margin: 4px 0; padding: 4px; }
.inline { display: inline; background: #afd; padding: 4px; }
</style>
</head>
<body>
<div class="container">
<div class="block">Block 1: займає всю ширину</div>
<div class="block">Block 2: стає нижче</div>
<span class="inline">Inline 1</span>
<span class="inline">Inline 2 - той самий рядок</span>
</div>
</body>
</html>Два block div складаються вертикально. Два inline span ідуть поруч на одному рядку. Якщо спробувати задати width: 200px для inline span, нічого не відбудеться.
Перемикання sidebar у React
function Sidebar({ isOpen }) {
return (
<nav
style={{
display: isOpen ? 'flex' : 'none',
flexDirection: 'column',
width: 240,
background: '#f5f5f5',
}}
>
<a href="/dashboard">Дашборд</a>
<a href="/settings">Налаштування</a>
</nav>
);
}
// isOpen=true -> flex-колонка навігації видима
// isOpen=false -> повністю видалена з layout, прогалини немаєКоли isOpen дорівнює false, навігація займає нульовий простір і основний контент розширюється на все місце. Це стандартний патерн у Material-UI drawer і Chakra UI sidebar.
Auto margin у flex-контейнері (edge case рівня senior)
.toolbar {
display: flex;
height: 50px;
align-items: center;
padding: 0 16px;
}
.logo { flex: none; }
.spacer { margin-left: auto; } /* відштовхує nav до правого краю */
.nav { display: flex; gap: 16px; }<div class="toolbar">
<img class="logo" src="logo.svg" alt="Logo">
<div class="spacer"></div>
<nav class="nav">
<a href="/">Головна</a>
<a href="/docs">Документація</a>
</nav>
</div>margin-left: auto на .spacer поглинає весь вільний горизонтальний простір і притискає навігацію до правого краю. Стандартний flex-трюк для toolbar без абсолютного позиціонування.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.