HTML & CSS

Блокова модель CSS. Відступи. Box Sizing

Глибоке занурення у блокову модель CSS: content, padding, border, margin, box-sizing, margin collapse, display-типи (block, inline, inline-block), overflow та visibility.

Блокова модель CSS. Відступи. Box Sizing

Чому елемент шириною 200px займає 240px?

Уявіть, що ви верстаєте макет: дизайнер каже, що картка має бути 200 пікселів завширшки. Ви пишете width: 200px, додаєте трохи внутрішніх відступів (padding: 20px) — і раптом картка стає 240px. Дві такі картки поруч вже не вміщуються в контейнер. Знайомо?

Ця «загадка» — не баг браузера, а фундаментальна концепція CSS, яку називають блоковою моделлю (Box Model). Кожен HTML-елемент на сторінці — це «коробка» (box) з кількома шарами. І поки ви не зрозумієте, як ці шари взаємодіють, верстка буде повна сюрпризів.

У попередній статті ми навчились вибирати елементи через селектори. Тепер прийшов час зрозуміти, з чого складається кожен вибраний елемент і як контролювати його розміри та відступи.


Анатомія блокової моделі

Кожен елемент у CSS — це прямокутна коробка, що складається з чотирьох концентричних шарів (від внутрішнього до зовнішнього):

Loading diagram...
graph TB
    subgraph M["margin — зовнішній відступ"]
        subgraph B["border — рамка"]
            subgraph P["padding — внутрішній відступ"]
                C["content — вміст"]
            end
        end
    end
    style C fill:#3b82f6,color:#fff,stroke:#1d4ed8
    style P fill:#93c5fd,color:#1e293b,stroke:#3b82f6
    style B fill:#f59e0b,color:#1e293b,stroke:#b45309
    style M fill:#64748b,color:#fff,stroke:#334155
Content (вміст)
area
Це простір для тексту, зображень, дочірніх елементів — того, що ви бачите. Саме до цієї області застосовуються width і height (за замовчуванням).
Padding (внутрішній відступ)
length
Простір між вмістом та рамкою. Padding «розсуває» елемент зсередини. Фон елемента (background-color) поширюється і на padding.
Border (рамка)
length + style + color
Видима межа елемента. Має три компоненти: товщину, стиль (solid, dashed, dotted...) та колір.
Margin (зовнішній відступ)
length
Простір між елементом та його сусідами. Margin завжди прозорий — фон через нього не видно.

Живий приклад: чотири шари

🔒localhost:3000

Розберемо, який фактичний розмір займає цей елемент:

ШарЛівоПравоРазом по горизонталі
Content200px
Padding20px20px40px
Border5px5px10px
Видима ширина250px
Margin30px30px60px
Повна ширина (з margin)310px
За замовчуванням width: 200px задає ширину лише content. Padding і border додаються поверх. Це поведінка box-sizing: content-box — значення за замовчуванням у CSS. Саме через це елемент «ширший», ніж ви очікували.

Властивості padding, border, margin

Padding — внутрішній відступ

Padding створює простір між вмістом і рамкою. Він «дихання» для тексту всередині елемента:

🔒localhost:3000

Скорочений запис padding:

СинтаксисЗначення
padding: 10px;Всі 4 сторони — 10px
padding: 10px 20px;Верх/низ — 10px, ліво/право — 20px
padding: 10px 20px 15px;Верх — 10px, ліво/право — 20px, низ — 15px
padding: 10px 20px 15px 5px;Верх → право → низ → ліво (за годинниковою стрілкою)
Запам'ятовуйте порядок за годинниковою стрілкою: Top → Right → Bottom → Left (мнемоніка — TRouBLe — «проблема»).

Також доступні окремі властивості для кожної сторони:

.element {
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 15px;
    padding-left: 5px;
}

Border — рамка

Рамка розташована між padding та margin. Вона має три компоненти:

🔒localhost:3000

Скорочений запис: border: товщина стиль колір;

.element {
    border: 2px solid #3b82f6;
}

/* Еквівалент */
.element {
    border-width: 2px;
    border-style: solid;
    border-color: #3b82f6;
}

Окремі сторони: border-top, border-right, border-bottom, border-left.

border-radius — заокруглення кутів:

🔒localhost:3000
border-radius: 50% перетворює квадрат на коло. Для прямокутника з різними сторонами — вийде еліпс. Цей прийом часто використовується для аватарів.

Margin — зовнішній відступ

Margin створює прозорий простір між елементом і його сусідами:

🔒localhost:3000

Синтаксис скорочення ідентичний padding — порядок за годинниковою стрілкою (top → right → bottom → left).

Важлива відмінність від padding: margin може мати від'ємні значення:

.overlap {
    margin-top: -20px; /* Елемент «заїде» на попередній на 20px */
}
Від'ємні margin — потужний, але небезпечний інструмент. Вони можуть спричинити перекриття елементів і неочікувані візуальні ефекти. Використовуйте обачно.

box-sizing — революція розрахунку розмірів

Згадайте проблему з початку статті: width: 200px + padding: 20px + border: 5px = 250px видимої ширини. Це поведінка content-box — значення за замовчуванням.

CSS пропонує альтернативу: border-box.

width задає ширину лише content. Padding і border додаються поверх:

🔒localhost:3000

Розрахунок: 200 (content) + 20×2 (padding) + 5×2 (border) = 250px

::

width задає ширину всієї видимої коробки (content + padding + border). Браузер автоматично зменшує content, щоб все вмістилось:

🔒localhost:3000

Розрахунок: 200px (загальна видима ширина) = 150 (content, автоматично) + 20×2 (padding) + 5×2 (border)

::

Loading diagram...
graph LR
    subgraph CB["content-box"]
        direction LR
        A["width: 200px"] --> B["content = 200px"]
        B --> C["+ padding 40px"]
        C --> D["+ border 10px"]
        D --> E["Видима = 250px ❌"]
    end
    subgraph BB["border-box"]
        direction LR
        F["width: 200px"] --> G["Видима = 200px ✅"]
        G --> H["border 10px"]
        H --> I["padding 40px"]
        I --> J["content = 150px"]
    end
    style E fill:#ef4444,color:#fff
    style G fill:#10b981,color:#fff

Глобальний border-box — стандарт індустрії

У реальних проєктах завжди використовують border-box для всіх елементів. Це робиться через універсальний селектор:

/* CSS Reset — стандарт у кожному проєкті */
*,
*::before,
*::after {
    box-sizing: border-box;
}
Цей код зустрічається буквально в кожному професійному CSS-файлі. Ми додаємо ::before та ::after, щоб псевдоелементи теж підкорялись border-box. Запам'ятайте цей патерн — вам слід завжди починати з нього.

Центрування блоків з margin: auto

Один із найпоширеніших прийомів — горизонтальне центрування блокового елемента:

🔒localhost:3000

Як це працює: коли елемент має фіксовану width, а margin-left і margin-right встановлені в auto, браузер рівномірно розподіляє вільний простір між лівим та правим відступами.

margin: auto працює для горизонтального центрування тільки для блокових елементів з явно заданою шириною. Для вертикального центрування margin: auto не працює у звичайному потоці — для цього використовують Flexbox або Grid (розглянемо в наступних статтях).

Колапс марджинів (Margin Collapse)

Це один із найнесподіваніших механізмів CSS, що спантеличує навіть досвідчених розробників.

Що таке колапс?

Коли два вертикальні margin стикаються, вони не додаються, а зливаються — залишається більший з двох:

🔒localhost:3000
Loading diagram...
graph LR
    A["Блок A\nmargin-bottom: 30px"] --- B["Результат:\n30px (а не 50px)"] --- C["Блок B\nmargin-top: 20px"]
    style A fill:#3b82f6,color:#fff
    style B fill:#f59e0b,color:#fff
    style C fill:#10b981,color:#fff

Правила колапсу

✅ Колапсує

  • Вертикальні margin суміжних блокових елементів
  • Margin батька та першого/останнього дочірнього елемента (якщо між ними немає padding, border або вмісту)
  • Margin порожнього елемента (верхній і нижній зливаються)

❌ Не колапсує

  • Горизонтальні margin (left/right) — ніколи
  • Елементи з display: flex або display: grid
  • Елементи з overflow відмінним від visible
  • Елементи з float або position: absolute
  • Елементи, розділені padding або border батька

Колапс батько-дитина

Це ще підступніший випадок — margin дочірнього елемента «витікає» назовні батька:

🔒localhost:3000
Найпростіші способи запобігти колапсу батько-дитина:
  • Додайте padding-top: 1px (або будь-яке значення) батьку
  • Додайте border-top: 1px solid transparent батьку
  • Додайте overflow: hidden батьку
  • Використайте display: flex або display: grid на батьку (вони повністю вимикають margin collapse)

display: block, inline, inline-block

Кожен HTML-елемент має тип відображення за замовчуванням — блоковий або рядковий. Цей тип визначає, як елемент поводиться у потоці документа.

display: block

Блокові елементи займають всю доступну ширину і починаються з нового рядка:

🔒localhost:3000

Блокові за замовчуванням: <div>, <p>, <h1><h6>, <section>, <article>, <ul>, <ol>, <li>, <header>, <footer>, <form>.

Характеристики:

  • Починається з нового рядка
  • Займає всю доступну ширину батька (якщо не задана width)
  • Реагує на width, height, margin, padding — повністю

display: inline

Рядкові елементи займають лише стільки місця, скільки потрібно для вмісту, і не переносяться на новий рядок:

🔒localhost:3000

Рядкові за замовчуванням: <span>, <a>, <strong>, <em>, <code>, <img>, <input>.

Для inline-елементів width, height, margin-top та margin-bottomне працюють. Діють лише горизонтальні margin-left/margin-right та padding (але вертикальний padding не впливає на висоту рядка).

display: inline-block

Гібрид, що поєднує найкраще з обох світів: елемент залишається в потоці рядка, але підтримує блокові властивості:

🔒localhost:3000

Порівняльна таблиця

Характеристикаblockinlineinline-block
Новий рядок
Ширина на весь рядок
width / height
Вертикальний margin
Горизонтальний margin
padding (повний)⚠️ (не впливає на layout)
display: none — ще одне важливе значення. Воно повністю видаляє елемент з потоку документа — він не займає місця і не відображається. Про різницю з visibility: hidden — нижче.

width та height — контроль розмірів

Базові властивості

.element {
    width: 300px; /* Фіксована ширина */
    height: 200px; /* Фіксована висота */
}

min- та max- обмеження

Часто задавати жорстку ширину — погана ідея (сторінка має бути адаптивною). Натомість використовують обмеження:

.card {
    width: 100%; /* Займай всю ширину батька */
    max-width: 600px; /* Але не більше 600px */
    min-width: 280px; /* І не менше 280px */
}
🔒localhost:3000
Патерн width: 100%; max-width: Npx; margin: 0 auto; — це стандартний спосіб створити центрований контейнер, що адаптується до малих екранів. Ви побачите його на більшості сайтів.

height: auto та проблема фіксованої висоти

Уникайте фіксованої height для текстового контенту. Якщо тексту стане більше (наприклад, через переклад), він «вилізе» за межі елемента. Натомість дозвольте висоті визначатися автоматично (height: auto — значення за замовчуванням), а для обмежень використовуйте min-height.
/* ❌ Погано — текст може переповнити */
.card {
    height: 200px;
}

/* ✅ Добре — мінімальна висота, але контент може розширити */
.card {
    min-height: 200px;
}

Overflow — контроль переповнення

Що станеться, коли вміст не вміщується у задані розміри? Це контролює властивість overflow:

Вміст виходить за межі елемента і перекриває сусідів:

🔒localhost:3000

::

Вміст обрізається — те, що не вміщується, не видно:

🔒localhost:3000

З'являються смуги прокрутки (завжди, навіть якщо вміст вміщується):

🔒localhost:3000

Смуги прокрутки з'являються тільки за потреби:

🔒localhost:3000

::

Також доступні осьові варіанти: overflow-x (горизонтальна прокрутка) та overflow-y (вертикальна прокрутка):

.horizontal-scroll {
    overflow-x: auto; /* Горизонтальний скрол за потреби */
    overflow-y: hidden; /* Вертикальний — приховати */
}

visibility: hidden vs display: none

Обидві властивості «приховують» елемент, але принципово по-різному:

🔒localhost:3000
Характеристикаvisibility: hiddendisplay: none
Елемент видимий
Займає місце в потоці
Доступний для скрін-рідерів
Дочірні елементиМожуть бути visibility: visibleПовністю приховані
Анімація приховуванняПідтримує transitionНе підтримує
Коротко: visibility: hidden — це «невидимий, але він тут». display: none — це «його не існує».

outline — не плутайте з border

Є ще одна «рамка», про яку варто знати — outline. Вона виглядає схоже на border, але має ключову відмінність:

.element:focus {
    outline: 3px solid #3b82f6;
    outline-offset: 2px;
}

Border

  • Є частиною блокової моделі
  • Впливає на розмір елемента
  • Може мати різні стилі на різних сторонах
  • Підтримує border-radius

Outline

  • Не є частиною блокової моделі
  • Не впливає на розмір та позицію
  • Однаковий з усіх сторін
  • Не підтримує різні сторони
Ніколи не видаляйте outline на елементах фокусу (outline: none) без заміни! Це критично для доступності — користувачі, що навігують клавіатурою (Tab), орієнтуються саме по outline. Якщо стандартний outline не підходить — замініть його кастомним стилем :focus-visible.

Практичні завдання

Рівень 1 — Базовий

Рівень 2 — Логіка та комбінування

Рівень 3 — Створення з нуля


Підсумок

📦 Блокова модель

Кожен елемент — це коробка з 4 шарами: content → padding → border → margin.

📐 box-sizing

border-box робить width інтуїтивним: padding і border входять у задану ширину. Завжди використовуйте глобальний *, *::before, *::after { box-sizing: border-box; }.

💥 Margin Collapse

Вертикальні margin зливаються (залишається більший). Padding, border, overflow, display: flex/grid — блокують колапс.

🔀 Display

block — новий рядок, вся ширина. inline — в потоці тексту, ігнорує width/height. inline-block — гібрид з перевагами обох.

Корисні посилання