Skip to main content

Властивість рендеринг CSS

CSS display - властивість, яка визначає як елемент бере участь у розмітці сторінки: блок, inline-бокс, flex/grid контейнер або нічого.

Теорія

TL;DR

  • block займає весь рядок: новий рядок, повна ширина батьківського контейнера, розміри задаються
  • inline тече всередині тексту: без переносу рядка, ігнорує явні width та height
  • inline-block розміщується inline, але приймає розміри (ідеально для кнопок і бейджів)
  • flex і grid перетворюють елемент на контейнер компонування для дочірніх елементів
  • none повністю виключає елемент з розмітки, місце не резервується

Швидкий приклад

html
<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Блоковий боксПовна ширина батькаТакСекції, картки, навбари
inlineInline-боксЗа контентомНіТекстові spans, іконки в тексті
inline-blockInline-blockЗадається явноНіКнопки, поля форм
flexFlex-контейнерГнучкаТакРядкові/колонкові макети
gridGrid-контейнерЗа сіткоюТак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.

css
/* Неправильно - 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.

css
/* Неправильно - картки вирівнюються по baseline і скачуть */ .card { display: inline-block; } /* Правильно */ .card { display: inline-block; vertical-align: top; }

inline-block за замовчуванням вирівнюється по baseline тексту. Якщо картки різної висоти, вони збиваються в різних напрямках. vertical-align: top виправляє це.

Помилка 3: display: flex на <ul> без скидання стилів списку.

css
/* Неправильно - маркери вилазять за межі 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 поруч

html
<!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

jsx
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)

css
.toolbar { display: flex; height: 50px; align-items: center; padding: 0 16px; } .logo { flex: none; } .spacer { margin-left: auto; } /* відштовхує nav до правого краю */ .nav { display: flex; gap: 16px; }
html
<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 без абсолютного позиціонування.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?