Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Властивість рендеринг CSS». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**CSS `display`** - визначає як елемент бере участь у розмітці: блок, inline-бокс, flex/grid контейнер або нічого. `block` займає повну ширину на новому рядку. `inline` тече в тексті й ігнорує `width`/`height`. `none` видаляє елемент з потоку повністю, без резервування місця. **Головне:** `inline` ігнорує явні розміри. Для inline-елемента з контрольованими розмірами використовуй `inline-block`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**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` | Блоковий бокс | Повна ширина батька | Так | Секції, картки, навбари | | `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`.** ```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 без абсолютного позиціонування.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.