Box model: content, padding, border, margin — как складываются размеры (CSS)

Блочная модель (box model) — это фундамент того, как браузер рисует почти любой HTML‑элемент. По сути, это набор правил, по которым вычисляются итоговые габариты элемента и то, сколько места он реально занимает на странице. Если не понимать, как работает box model, можно легко столкнуться с «поехавшей» вёрсткой: блоки вылезают за границы, отступы оказываются не такими, как ты планировал, а соседние элементы встают не туда.


Content — базовая область, где живёт контент

Content — это самая внутренняя часть блока, та самая, где отображается текст, картинки, видео, кнопки и всё остальное, что ты положил внутрь тега. Именно к этой области изначально относятся свойства width и height: если ты пишешь width: 200px, то при стандартной модели это означает «контент должен быть шириной 200 пикселей».

Пример:

css
.box {
  width: 200px;
  height: 100px;
  background-color: lightblue;
}

HTML:

html
<div class="box">Текст</div>

На этом этапе блок имеет размер ровно 200×100 px — и это только контент. Важно понимать, что сюда ещё не входят никакие отступы и рамки: это «чистая» область под содержимое. Именно от неё дальше начинают «наращиваться» остальные слои.


Padding — внутренний отступ: пространство между контентом и рамкой

Padding — это пространство, которое ты оставляешь между содержимым и границей элемента. Его используют, чтобы контент не прилипал к краям блока, не касался рамки и вообще выглядел аккуратно.

Пример:

css
.box {
  padding: 20px;              /* отступ по 20 px со всех сторон */
  /* или раздельно */
  /* padding-top: 10px;      */
  /* padding-right: 20px;     */
  /* padding-bottom: 10px;   */
  /* padding-left: 20px;     */
}

Что происходит с размерами:

  • Если модель content-box (по умолчанию), то padding прибавляется к width и height.
  • Фон элемента (свойство background) распространяется на padding: визуально ты видишь цвет фона и под контентом, и под отступами.

Для нашего примера:

  • ширина контента: 200 px
  • padding слева и справа: 20 + 20 = 40 px
  • итоговая ширина блока до рамки: 240 px

То есть padding напрямую влияет на визуальные размеры блока и на то, насколько «просторно» выглядит содержимое.


Border — рамка: граница вокруг контента и padding

Border — это линия, которая идёт сразу после padding и очерчивает блок. Она задаётся тремя параметрами: толщиной, стилем (например, solid, dashed, dotted) и цветом.

Пример:

css
.box {
  border: 5px solid red;
}

Это значит: толщина 5 px, стиль solid (сплошная линия), цвет красный.

Как border влияет на размеры:

  • При content-box рамка добавляется поверх ширины контента и padding.
  • У рамки нет фона: это отдельный слой, который не заливается цветом из background.

Продолжая наш пример:

  • текущая ширина до рамки: 240 px
  • border слева и справа: 5 + 5 = 10 px
  • итоговая ширина блока: 250 px

Таким образом, border тоже увеличивает габариты блока. Это важно помнить, когда ты жёстко задаёшь width и потом добавляешь рамку: блок может стать шире, чем ты ожидал.


Margin — внешний отступ: расстояние до соседей

Margin — это прозрачное пространство вокруг border. Оно не имеет цвета, фона или толщины: это просто «пустота», которая отодвигает блок от соседних элементов.

Пример:

css
.box {
  margin: 15px;
  /* или раздельно */
  /* margin-top: 10px;       */
  /* margin-right: 15px;     */
  /* margin-bottom: 10px;    */
  /* margin-left: 15px;      */
}

Важные особенности margin:

  • Он не входит в габариты самого блока (не влияет на его «внутреннюю» ширину и высоту).
  • Но он влияет на то, сколько места блок занимает на странице вместе с соседями.
  • Вертикальные margin (top/bottom) у соседних блочных элементов могут схлопываться (margin collapse): браузер берёт большее из двух значений, а не суммирует их. Это сделано специально, чтобы избежать двойных отступов между абзацами и заголовками.

Если считать «всё место на экране», которое блок фактически занимает вместе с отступом до соседей:

  • ширина блока с border: 250 px
  • margin слева и справа: 15 + 15 = 30 px
  • общее место по горизонтали: 280 px

Две модели расчёта размеров: content-box и border-box

В CSS есть два принципиально разных способа считать итоговую ширину и высоту элемента. От этого зависит, как будут складываться width, padding и border.

box-sizing: content-box — поведение по умолчанию

При content-box свойства width и height относятся только к контенту. Всё остальное (padding и border) прибавляется сверху.

Формулы:

  • ширина блока: width + padding-left + padding-right + border-left + border-right
  • высота блока: height + padding-top + padding-bottom + border-top + border-bottom

Пример:

css
.box {
  box-sizing: content-box;   /* это значение по умолчанию */
  width: 200px;
  padding: 20px;
  border: 5px solid red;
}

Реальная ширина блока: 200 + 20 + 20 + 5 + 5 = 250px.

Это часто становится причиной сюрпризов: ты задаёшь width: 300px для карточки, добавляешь padding: 16px и border: 1px, а карточка внезапно становится 334 px и ломает сетку.


box-sizing: border-box — более предсказуемая модель

При border-box заданные width и height включают в себя контент, padding и border. То есть ты говоришь «хочу блок ровно 200 px», и он будет ровно 200 px, даже если добавишь padding и border — они «съедят» место внутри, а не снаружи.

Формула фактически такая:

  • заданная ширина = padding-left + padding-right + border-left + border-right + content-width

Пример:

css
.box {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid red;
}

Реальная ширина блока — ровно 200 px. При этом ширина контента (внутренней области) автоматически уменьшается, чтобы всё влезло в заданный размер.

На практике border-box гораздо удобнее: ты можешь спокойно добавлять padding и border, не боясь, что блок станет шире.


Как это используют на практике: универсальный сброс box-sizing

Чтобы избежать неожиданностей, во многих проектах сразу задают:

css
* {
  box-sizing: border-box;
}

Звёздочка * — это универсальный селектор: правило применяется ко всем элементам на странице. В результате любой элемент с width: Xpx будет занимать ровно Xpx по ширине (без учёта margin). Margin по‑прежнему остаётся отдельным отступом до соседей и не влияет на внутренние габариты блока.

Такой подход сильно упрощает вёрстку: ты перестаёшь каждый раз держать в голове, «а сколько там ещё прибавится от padding и border».


Частые ошибки и как их избежать

  • Забывают про border при расчёте ширины. Если у тебя сетка из колонок по 33.33% и ты добавляешь border, колонки могут не влезть в строку. Решение: использовать border-box.
  • Дублируют отступы через margin и padding. Например, делают padding: 20px внутри карточки и ещё margin: 20px между карточками. Иногда это нормально, но часто приводит к слишком большим расстояниям. Лучше чётко разделить: padding — для «воздуха» внутри, margin — для расстояния между блоками.
  • Не учитывают схлопывание margin. Вертикальные отступы между соседними блоками не складываются, а берут максимум. Если ты ожидаешь 40 px (20+20), а получаешь 20 px — это как раз margin collapse.

Пример целиком: один и тот же блок в двух моделях

Вариант 1: content-box

css
.box-content {
  box-sizing: content-box;
  width: 200px;
  padding: 20px;
  border: 5px solid red;
  margin: 15px;
}

Итоговая ширина блока: 200 + 40 + 10 = 250px (margin не входит в размер блока, но добавляет место на странице).

Вариант 2: border-box

css
.box-border {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid red;
  margin: 15px;
}

Итоговая ширина блока — ровно 200px. Контент внутри автоматически сожмётся, чтобы всё поместилось.

Добавить комментарий