Блочная модель
Блочная модель (box model) — фундаментальная концепция CSS, описывающая каждый элемент как прямоугольник из четырёх областей: content, padding, border и margin.
Зачем нужно
Каждый HTML-элемент — это прямоугольник. Блочная модель определяет, как рассчитываются его реальные размеры. Без понимания box model невозможно точно управлять отступами, границами и размерами элементов.
Где используется
- Расчёт реальных размеров любого элемента
- Управление внутренними и внешними отступами
- Создание границ и рамок
- Разрешение проблем с «неожиданной» шириной элементов
Предпосылки
- Что такое CSS
- Единицы измерения — единицы для размеров
Четыре области box model
┌──────────────── margin ─────────────────┐
│ │
│ ┌──────────── border ───────────────┐ │
│ │ │ │
│ │ ┌──────── padding ───────────┐ │ │
│ │ │ │ │ │
│ │ │ ┌────── content ──────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ Текст / дети │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
content — область содержимого
.box {
width: 300px; /* ширина content */
height: 200px; /* высота content */
/* Ограничения */
min-width: 200px;
max-width: 500px;
min-height: 100px;
max-height: 400px;
}
padding — внутренний отступ
Пространство между содержимым и границей. Фон элемента распространяется на padding.
.box {
/* Все стороны */
padding: 20px;
/* Вертикаль | Горизонталь */
padding: 10px 20px;
/* Верх | Горизонталь | Низ */
padding: 10px 20px 30px;
/* Верх | Право | Низ | Лево (по часовой) */
padding: 10px 20px 30px 40px;
/* Отдельные стороны */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
/* Логические свойства */
padding-block: 10px 30px; /* верх и низ */
padding-inline: 20px 40px; /* лево и право */
}
border — граница
.box {
/* Сокращённая запись: ширина | стиль | цвет */
border: 2px solid #333;
/* Отдельные стороны */
border-top: 1px dashed red;
border-bottom: 3px double blue;
/* Отдельные свойства */
border-width: 1px 2px 3px 4px;
border-style: solid;
border-color: #333;
/* Скругление углов */
border-radius: 8px;
border-radius: 50%; /* круг (если width = height) */
border-radius: 10px 20px 30px 40px; /* каждый угол */
/* Логические свойства */
border-block: 1px solid #ddd;
border-inline-start: 4px solid blue;
}
Стили границ:
.borders {
border-style: solid; /* сплошная линия */
border-style: dashed; /* штрихи */
border-style: dotted; /* точки */
border-style: double; /* двойная */
border-style: groove; /* объёмная вдавленная */
border-style: ridge; /* объёмная выпуклая */
border-style: inset; /* вдавленная рамка */
border-style: outset; /* выпуклая рамка */
border-style: none; /* без границы */
}
margin — внешний отступ
Пространство снаружи границы. Фон НЕ распространяется на margin.
.box {
/* Все стороны */
margin: 20px;
/* Центрирование блока по горизонтали */
margin: 0 auto;
/* Отдельные стороны */
margin-top: 20px;
margin-bottom: 30px;
/* Отрицательные отступы — элемент сдвигается */
margin-top: -10px;
margin-left: -20px;
/* Логические свойства */
margin-block: 20px;
margin-inline: auto; /* центрирование */
}
box-sizing — как считать размеры
content-box (по умолчанию)
width/height задают размер только content. Padding и border добавляются сверху.
.box-content {
box-sizing: content-box;
width: 300px;
padding: 20px;
border: 2px solid black;
/* Реальная ширина = 300 + 20*2 + 2*2 = 344px */
}
border-box (рекомендуемый)
width/height включают content + padding + border. Размер предсказуемый.
.box-border {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 2px solid black;
/* Реальная ширина = 300px (content сжимается до 256px) */
}
Глобальный сброс (обязательная практика)
/* Включить border-box для ВСЕХ элементов */
*,
*::before,
*::after {
box-sizing: border-box;
}
Практически все современные проекты используют
border-boxглобально. Это первое правило в любом CSS-файле.
Схлопывание margin (margin collapsing)
Вертикальные margin соседних блочных элементов объединяются — берётся больший из двух:
.block-a {
margin-bottom: 30px;
}
.block-b {
margin-top: 20px;
}
/* Расстояние между ними = 30px (не 50px!) */
/* Берётся больший margin */
Когда margin схлопывается
- Соседние элементы — вертикальные margin смежных блоков
- Родитель и первый/последний ребёнок — если нет padding, border или содержимого между ними
- Пустой блок — его собственные
margin-topиmargin-bottomсхлопываются
/* Проблема: margin ребёнка "выпадает" из родителя */
.parent {
background: lightblue;
/* margin-top ребёнка "выпадет" наружу */
}
.child {
margin-top: 50px; /* Сдвинет .parent вниз! */
}
/* Решения: */
.parent {
/* Вариант 1: padding */
padding-top: 1px;
/* Вариант 2: border */
border-top: 1px solid transparent;
/* Вариант 3: overflow */
overflow: hidden;
/* Вариант 4: display: flow-root */
display: flow-root;
}
Когда margin НЕ схлопывается
- Элементы с
float - Элементы с
position: absolute/fixed - Flex-элементы и grid-элементы
- Элементы с
overflowотличным отvisible - Горизонтальные margin (только вертикальные схлопываются)
outline — не часть box model
.box {
/* outline НЕ занимает место, НЕ влияет на размеры */
outline: 2px solid blue;
outline-offset: 4px; /* отступ от border */
}
/* Используется для фокуса */
button:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}
/* Никогда не убирайте outline без замены! */
button:focus {
outline: none; /* Плохо для доступности */
}
button:focus-visible {
outline: 2px solid #007bff; /* Хорошо — только для клавиатуры */
}
display и box model
/* Block — занимает всю ширину, можно задать width/height/margin */
.block { display: block; }
/* Inline — ширина по содержимому, вертикальные margin/padding
НЕ влияют на поток */
.inline { display: inline; }
/* Inline-block — inline снаружи, block внутри
Можно задать width/height/margin */
.inline-block { display: inline-block; }
Просмотр box model в DevTools
В Chrome DevTools:
- Правый клик на элемент → «Inspect»
- Вкладка «Computed» показывает box model визуально
- Наведение на элемент подсвечивает: content (синий), padding (зелёный), border (жёлтый), margin (оранжевый)
Частые ошибки
- Забыли
box-sizing: border-box— элемент шире ожидаемого:/* ОШИБКА */ .col { width: 50%; padding: 20px; } /* Реальная ширина = 50% + 40px → выходит за контейнер */ - Margin на inline-элементах — вертикальные отступы не работают:
/* НЕ сработает */ span { margin-top: 20px; } /* Нужен display: inline-block или block */ - Неожиданное схлопывание margin — особенно «выпадение» margin ребёнка из родителя
- Удаление
outlineпри фокусе — нарушает доступность для клавиатурной навигации
Практика
- Создать элемент и посмотреть box model в DevTools
- Сравнить
content-boxиborder-boxна элементе с padding - Воспроизвести схлопывание margin и исправить через
display: flow-root - Центрировать блок через
margin: 0 auto - Добавить
box-sizing: border-boxглобально и проверить результат
Связанные темы
- Единицы измерения — единицы для задания размеров
- Логические свойства — margin-block, padding-inline
- Основы Grid — grid-элементы не схлопывают margin