CSS

CSS: box model и box-sizing

📚 22 вопросовПройти тест →
Лекция

CSS: box model и box-sizing

CSS

CSS: box model и box-sizing

Введение: как коробка с вещами 📦

Представьте коробку: внутри содержимое, вокруг прокладка, потом стенки, а снаружи пространство до другой коробки. В CSS каждый блок устроен так же.
Если не учитывать эту модель, ширина «вдруг» становится больше ожидаемой, и верстка ломается.
💡 Совет: сначала поймите, как браузер считает размеры блока, и только потом настраивайте сетку.
Вывод: box model — это база, без которой сложно делать стабильный layout.

Проблема: блоки ломают ширину ❌

Без понимания box model:
  • элемент вылезает за контейнер;
  • карточки в ряд не помещаются;
  • отступы ведут себя неожиданно.
С пониманием модели:
  • ширина считается предсказуемо;
  • компоненты легко выравниваются;
  • адаптивность работает стабильно.
Вывод: большинство «сломанных» блоков — это ошибка расчёта размеров, а не проблема flex/grid.

Чем помогает и как работает

  • объясняет, из каких частей состоит визуальный блок;
  • позволяет точно контролировать итоговые размеры;
  • снижает количество layout-багов в адаптивной верстке.
Как это работает:
  1. Браузер считает размер блока через content + padding + border (+ margin снаружи).
  2. При content-box ширина относится только к контенту.
  3. При border-box ширина уже включает padding и border.
  4. Отступы между элементами управляются через margin, внутренние поля — через padding.
Вывод: если правильно выбрать box-sizing и роль отступов, разметка становится предсказуемой.

Ключевые термины (простыми словами)

  • Box model — модель коробки элемента в CSS.
  • Content — внутреннее содержимое блока.
  • Padding — внутренний отступ до границы блока.
  • Border — рамка элемента.
  • Margin — внешний отступ между элементами.
  • content-box — ширина/высота считаются только для content.
  • border-box — ширина/высота включают padding и border.
  • Margin collapse — схлопывание вертикальных margin между соседними блоками.
Вывод: эти термины нужно знать для любой практической работы с layout.

1. Из чего состоит box model

Назначение: понять, из каких частей складывается реальный размер любого блока.
Простыми словами: у каждого элемента есть "слои коробки": контент, внутренний отступ, рамка и внешний отступ.
Для новичка: представьте посылку: товар внутри — это content, пупырка вокруг — padding, картон коробки — border, а расстояние между коробками на складе — margin. Когда понимаете эту аналогию, вся верстка становится намного проще.
Что это значит в цифрах:
  • внешняя ширина = content + padding-left + padding-right + border-left + border-right + margin-left + margin-right;
  • внешняя высота считается аналогично по вертикали.
Пример:
.card {  width: 300px;  padding: 16px;  border: 2px solid #94a3b8;  margin: 20px;}/* В режиме content-box:   итог по ширине = 300 + 32 + 4 + 40 = 376px */
🔎 Как это происходит на практике:
  1. В DevTools выбираю элемент и открываю схему Box Model.
  2. Сверяю по отдельности content, padding, border и margin.
  3. Проверяю, совпадает ли реальный размер с тем, который я ожидал в макете.
Характеристики:
  • ✅ content — зона, где живут текст, картинки, кнопки.
  • ✅ padding увеличивает внутренний воздух и зону взаимодействия.
  • ✅ border визуально отделяет блок, но тоже участвует в размере.
  • ✅ margin создаёт дистанцию между соседними блоками.
❗ Когда использовать: всегда, когда блок "не влезает", прыгает сетка или непонятно, откуда берётся лишняя ширина/высота.
Вывод: если считать размер через все слои box model, "магические" баги верстки исчезают.

2. content-box (по умолчанию)

Назначение: понять дефолтное поведение браузера, из-за которого блоки часто "распухают".
Простыми словами: в content-box свойство width задаёт только ширину контента; padding и border добавляются сверху.
Для новичка: если вы написали width: 200px, это не «полная ширина карточки», а только место под текст и картинку. Как только добавите padding и border, блок станет шире 200px, поэтому ряд может внезапно сломаться.
Пример:
.tile {  box-sizing: content-box;  width: 200px;  padding: 20px;  border: 2px solid #1e293b;}/* Реальная ширина = 200 + 40 + 4 = 244px */
🔎 Как это происходит на практике:
  1. Делаю карточку шириной 200px.
  2. Добавляю padding для воздуха и border для визуального контура.
  3. Получаю неожиданное переполнение ряда, потому что фактическая ширина уже 244px.
Характеристики:
  • ✅ Это стандартный режим браузера "из коробки".
  • ⚠️ Легко получить горизонтальный скролл или перенос карточек.
  • ✅ Подходит, если важно зафиксировать именно ширину контента (редкие случаи).
❗ Когда использовать: точечно, когда вы осознанно контролируете контентную область и готовы вручную учитывать добавки от padding и border.
Вывод: content-box полезен для понимания механики, но в боевой верстке часто создаёт лишние риски.

3. border-box (рекомендуется)

Назначение: сделать расчёт размеров предсказуемым для всей системы компонентов.
Простыми словами: при border-box объявленная ширина уже включает и padding, и border; контент автоматически "ужимается" внутрь заданного размера.
Для новичка: здесь width — это уже итоговый наружный размер блока. То есть карточка с width: 320px останется 320px, даже если вы добавили внутренние отступы и рамку. Браузер сам уменьшит внутреннюю область под контент, поэтому сетка не расползается.
Что это даёт на практике:
  • вы задали карточке width: 320px и она действительно остаётся 320px снаружи;
  • добавили внутренние отступы, но сетка не "поехала";
  • проще собирать колонки, где каждый пиксель важен.
Пример:
html {  box-sizing: border-box;} *,*::before,*::after {  box-sizing: inherit;} .card {  width: 320px;  padding: 24px;  border: 2px solid #8b5cf6;}/* Внешняя ширина = 320px (стабильно)   Ширина контента = 320 - 48 - 4 = 268px */
🔎 Как это происходит на практике:
  1. Один раз включаю глобальное правило на весь проект.
  2. Строю сетку (flex/grid) без ручных поправок "минус padding".
  3. Проверяю в DevTools: внешние размеры стабильно совпадают с дизайн-значениями.
  4. В компонентах оперирую понятной логикой: "ширина блока постоянна, внутренний воздух регулируется padding".
Характеристики:
  • ✅ Предсказуемая внешняя геометрия компонентов.
  • ✅ Меньше переполнений и меньше "костылей" в адаптиве.
  • ✅ Проще поддерживать дизайн-систему и повторяемые карточки.
  • ⚠️ В legacy-коде после переключения может потребоваться ревизия старых фиксированных размеров.
❗ Когда использовать: как дефолт проекта почти всегда: лендинги, админки, дашборды, каталоги, любые интерфейсы с карточками и сетками.
Вывод: border-box — это практический стандарт: меньше сюрпризов, быстрее разработка, стабильнее верстка.

4. Margin vs Padding

Назначение: чётко разделить, где "внутренний воздух" компонента, а где расстояние между компонентами.
Простыми словами:
  • padding — пространство внутри блока (между контентом и рамкой);
  • margin — расстояние снаружи блока (до соседей).
Для новичка: простое правило: если нужно "дать воздуху тексту внутри карточки" — это padding. Если нужно "отодвинуть одну карточку от другой" — это margin. От этого правила зависит аккуратность всего интерфейса.
Пример:
.card {  padding: 16px;      /* внутренний воздух */  margin-bottom: 24px;/* интервал до следующей карточки */  border-radius: 12px;}
🔎 Как это происходит на практике:
  1. Если текст "липнет" к краям карточки, увеличиваю padding.
  2. Если карточки стоят слишком близко друг к другу, регулирую margin.
  3. Проверяю, что фон карточки покрывает только её саму, а не расстояние между карточками.
Характеристики:
  • ✅ padding расширяет кликабельную и фоновую область элемента.
  • ✅ margin не красится фоном и не увеличивает зону клика.
  • ⚠️ Подмена ролей ломает ритм интерфейса и ощущение аккуратности.
❗ Когда использовать: padding — для "внутренней ergonomics" компонента; margin — для компоновки компонентов между собой.
Вывод: правильное разделение margin/padding делает макет читаемым и устойчивым при росте проекта.

5. Схлопывание margin (кратко)

Назначение: понимать, почему вертикальный отступ иногда меньше, чем "по математике".
Простыми словами: два вертикальных margin могут не суммироваться, а схлопнуться в один (обычно берётся больший).
Для новичка: если у верхнего блока снизу 24px, а у нижнего сверху 16px, между ними будет не 40px, а 24px. Это нормальное поведение CSS, а не ошибка браузера.
Где встречается:
  • у соседних блочных элементов в нормальном потоке;
  • между родителем и первым/последним дочерним блоком;
  • чаще всего в колонках текста и секциях.
Пример:
h2 { margin-bottom: 24px; }p  { margin-top: 16px; }/* Между ними будет 24px, а не 40px */
🔎 Как это происходит на практике:
  1. Выставляю вертикальные отступы заголовкам и абзацам.
  2. Визуально вижу интервал меньше ожидаемой суммы.
  3. Для контроля ритма переношу часть отступа в padding контейнера или создаю новый контекст (display: flow-root, overflow: auto).
  4. Помню, что в flex и grid схлопывание маргинов не работает.
Характеристики:
  • ✅ Влияет только на вертикальные margin в обычном потоке.
  • ✅ Не проявляется внутри flex/grid-контейнеров.
  • ⚠️ Часто создаёт ощущение "непредсказуемого" spacing у новичков.
❗ Когда использовать: когда настраиваете типографику, интервалы секций и хотите одинаковый вертикальный ритм без случайных провалов.
Вывод: зная правило схлопывания, вы управляете вертикальными отступами осознанно, а не подбором "на глаз".

Сравнение: content-box vs border-box

РежимЧто включает widthПрактика
content-boxтолько contentнужно вручную учитывать padding/border
border-boxcontent + padding + borderудобнее и предсказуемее в большинстве UI

Часто спрашивают на собеседованиях

  • Из чего состоит box model? content, padding, border, margin.
  • В чём разница между content-box и border-box? В том, что учитывает width.
  • Почему border-box часто рекомендуют глобально? Он упрощает расчёт размеров.
  • Чем padding отличается от margin? Внутренний vs внешний отступ.
  • Что такое схлопывание margin? Когда вертикальные margin сливаются в один.
Вывод: эти вопросы проверяют понимание основы layout, без которой сложно работать с CSS.

Типичные ошибки

Ошибка 1: Забыт box-sizing

❌ Неправильно: width рассчитан без учёта padding. ✅ Правильно: использовать border-box глобально.

Ошибка 2: Padding вместо margin

❌ Неправильно: ломается внешний ритм блоков. ✅ Правильно: padding внутри, margin между элементами.

Ошибка 3: Фиксированная ширина + padding

❌ Неправильно: блок вылезает за контейнер в content-box. ✅ Правильно: учитывать режим расчёта или использовать border-box.

Ошибка 4: Не учитывается схлопывание margin

❌ Неправильно: «почему отступ меньше, чем ожидалось?» ✅ Правильно: проверять вертикальные margin соседних блоков.

Best Practices

  • Включайте глобально box-sizing: border-box.
  • Явно разделяйте роли margin и padding.
  • Проверяйте итоговый размер блока в DevTools.
  • Держите систему отступов кратной базовому шагу (например 4/8).
  • Избегайте случайного переполнения фиксированных блоков.
  • Учитывайте схлопывание margin в текстовых секциях.

Заключение

Ключевые мысли

🎯 Box model объясняет итоговый размер элемента. 🎯 border-box обычно даёт более предсказуемую верстку. 🎯 Осознанная работа с margin/padding убирает хаос в интерфейсе.
Если правильно настроить модель коробки, layout становится стабильным и управляемым.
🎯

Проверьте знания

Закрепите материал — пройдите тест по теме «CSS: box model и box-sizing»

Пройти тест →