Модуль 1 · урок 3 з 14
Блокова модель і потік
Перш ніж розкладати блоки по сітці, треба розуміти, з чого складається один блок і за якими правилами він займає місце. Дев'ять із десяти «поламаних розкладок» — це насправді нерозуміння трьох речей: блокової моделі, злипання відступів і того, хто саме створює скрол.
З чого складається блок
Кожен елемент — це чотири вкладені прямокутники: вміст, внутрішній відступ (padding),
рамка (border) і зовнішній відступ (margin). Margin — єдиний з них,
що лежить зовні елемента: фон туди не заходить.
width задає ширину лише вмісту, тож падінги «розпирають» блок.
Рядок box-sizing: border-box робить поведінку такою, якої всі очікують./* стандартне скидання, яке ставлять у кожному проєкті */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }
Злипання вертикальних відступів
Це та поведінка, через яку «margin чомусь не працює». Два вертикальні відступи, що зустрілися, не додаються, а склеюються: береться більший з них.
.a { margin-bottom: 24px; }
.b { margin-top: 16px; }
/* відстань між .a і .b буде 24px, а не 40px */
Гірше те, що margin дитини може «вилізти» назовні батька й посунути весь батьківський блок.
Класична сцена: у картки задано padding: 0, всередині заголовок з
margin-top — і відступ з'являється над карткою, а не всередині.
| Що зупиняє злипання | Як це виглядає |
|---|---|
display: flex або grid у батька | Найчастіше саме так це й лікується сьогодні |
padding або border у батька | Навіть 1px рамки розриває склейку |
overflow: hidden / auto | Створює новий контекст форматування |
display: flow-root | Спеціально для цього й придуманий |
У новому коді вертикальні відступи між елементами майже не задають через margin.
Замість цього батько стає flex або grid і отримує gap.
Тоді злипання не існує як явище, і немає проблеми «останній елемент має зайвий відступ знизу».
Блочні й рядкові елементи
display | Поведінка | Приклад |
|---|---|---|
block | Займає всю ширину, приймає height і вертикальні margin | div, p, section |
inline | Ширина за вмістом, ігнорує height і вертикальні margin | span, a, em |
inline-block | Стоїть у рядку, але поводиться як блок усередині | Старий спосіб робити кнопки |
flex / grid | Блок, який керує розкладкою дітей | Контейнери |
none | Елемента немає в потоці взагалі | Приховування |
Класична пастка: спроба задати height або padding-top елементу
<span>. Вертикальні розміри для рядкових елементів просто ігноруються —
потрібен inline-block або inline-flex.
Хто створює скрол
overflow вирішує, що робити з вмістом, який не влазить. І саме він визначає,
де з'явиться смуга прокрутки — у панелі чи в усієї сторінки.
overflow: visible; /* за замовчуванням: вміст просто вилазить назовні */
overflow: hidden; /* обрізати, скролу немає */
overflow: auto; /* скрол з'являється лише коли потрібен — робочий варіант */
overflow: scroll; /* смуга завжди, навіть коли не треба */
overflow: clip; /* обрізати жорстко, без можливості прокрутити */
Щоб панель скролилась усередині, а не тягнула за собою сторінку, потрібні дві речі одночасно:
overflow: auto на самій панелі і обмежена висота в її батька
(minmax(0, 1fr) у grid або min-height: 0 у flex).
Без другої умови батьківський рядок просто виросте під вміст, і скрол переїде на всю сторінку.
Обмеження розмірів
.card {
width: 100%;
max-width: 420px; /* не ширше 420, але може бути вужчою */
min-height: 120px;
margin-inline: auto; /* центрування по горизонталі одним рядком */
}
.prose { max-width: 68ch; } /* довжина рядка для читабельності */
.thumb { aspect-ratio: 16 / 9; } /* висота рахується сама */
min-width і max-width завжди сильніші за width: якщо вони
конфліктують, виграє обмеження. Це зручно — можна сміливо писати width: 100%
і не боятись, що блок розтягнеться на весь монітор.