CSS box-sizing и блочная модель: как работает border-box на практике
Если вы когда-либо удивлялись, почему блок с шириной 300px внезапно «распух» после добавления padding и border — вам нужен CSS box-sizing: border-box. Это базовая, но критически важная тема блочной модели (CSS Box Model), которая экономит часы отладки и делает вёрстку предсказуемой.
Что такое блочная модель CSS (Box Model)?
Каждый элемент в браузере — это «коробка» из четырёх слоёв: content → padding → border → margin. Ширина и высота элемента зависят от того, учитываются ли padding и border внутри заданной ширины/высоты или прибавляются сверху.
- content — содержимое (текст, изображения).
- padding — внутренние отступы между контентом и рамкой.
- border — рамка вокруг элемента.
- margin — внешние отступы (не входят в размер коробки).
box-sizing: content-box vs border-box
По умолчанию большинство элементов используют content-box. Это означает: если вы задали width: 300px, то реальная занимаемая ширина будет 300 + padding-left + padding-right + border-left + border-right. В border-box всё наоборот: padding и border входят внутрь заданных 300px — поэтому итоговый размер остаётся ровно 300px.
.demo {
width: 300px;
padding: 20px;
border: 2px solid #4a90e2;
}
.content-box { box-sizing: content-box; background: #eaf3ff; }
.border-box { box-sizing: border-box; background: #d8f7e1; }
<div class="demo content-box">content-box: фактическая ширина 344px (300 + 20 + 20 + 2 + 2)</div>
<div class="demo border-box">border-box: фактическая ширина 300px</div>
Почему border-box «победил» в реальных проектах
- Проще считать: указали ширину — получили именно её, без сюрпризов.
- Сетки не «ломаются» при добавлении padding/border.
- Меньше переполнений (overflow) и горизонтальных скроллов на мобильных.
Глобальный reset box-sizing: два надёжных варианта
Чаще всего проект начинают с глобального reset, чтобы все элементы и псевдоэлементы считали размеры по border-box. Есть два популярных способа.
Вариант 1: простой и понятный
*, *::before, *::after {
box-sizing: border-box;
}
Плюсы: минимализм и предсказуемость. Минусы: иногда неудобно переопределять отдельные компоненты под content-box (если это вдруг нужно).
Вариант 2: наследование от html
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
Преимущество — гибкость. Можно локально задать container { box-sizing: content-box; } и все внутренние элементы легко переключатся на другую модель, если им прописать inherit.
Практика: частые задачи и решения
1) Ширина 100% с отступами без переполнения
Задача: сделать блок на всю ширину контейнера, но с приятным внутренним отступом. С content-box элемент может «вылезти» наружу. С border-box всё ровно.
.full {
width: 100%;
padding: 16px;
box-sizing: border-box;
background: #fffbe6;
border: 1px solid #f0d264;
}
2) Карточки в ряд с равными отступами
Сетки часто делают на Flex или Grid. C border-box внутренние отступы карточки не ломают раскладку, а gap отвечает за промежутки между карточками.
.cards {
display: flex;
gap: 16px; /* поддерживается современными браузерами */
}
.card {
flex: 1 1 calc(33.333% - 10.67px); /* для примера, или просто flex: 1 */
padding: 16px;
border: 1px solid #ddd;
box-sizing: border-box;
background: #fafafa;
}
Совет: если можно, используйте просто flex: 1 и задайте минимальные ширины через min-width. А внешние отступы — через gap, а не margin между карточками.
3) Формы и поля ввода
Инпуты с content-box «расползаются» при увеличении padding. Переключите их на border-box для стабильной ширины и красивых отступов внутри.
input, select, textarea {
width: 100%;
padding: 12px 16px;
border: 1px solid #cfd8dc;
border-radius: 6px;
box-sizing: border-box;
}
4) Компонентная настройка: когда нужен content-box
Редко, но бывает, что компонент полагается на content-box (например, сложный калькулятор размеров или анимация ширины контента без учёта рамок). Тогда локально переключаемся:
.widget {
box-sizing: content-box; /* локальное исключение */
}
.widget__inner {
width: 320px; /* теперь это только content */
padding: 20px;
border: 2px solid #333;
}
Как считать размеры: простые формулы
- content-box: итоговая ширина = width + padding-left + padding-right + border-left + border-right
- border-box: итоговая ширина = width (padding и border уже внутри)
Пример: width: 300px; padding: 20px; border: 2px. В content-box итог — 344px; в border-box — 300px. То же применимо к высоте.
Отладка в DevTools
Откройте вкладку Elements → Layout/Computed. Там есть визуальная схема box model. Наведите на элемент — увидите размеры content, padding, border и margin, а также увидите, не идёт ли переполнение по ширине/высоте.
Margin collapsing: важная особенность отступов
С схлопыванием внешних отступов (margin collapsing) часто путаются. Оно не связано с box-sizing, но влияет на итоговый отступ между блоками. Верхний margin дочернего блока может «слиться» с верхним margin родителя, образуя один суммарный отступ. Чтобы избежать, можно, например, добавить родителю padding-top, border-top или overflow: auto.
.parent {
/* padding или border сверху предотвратит схлопывание */
padding-top: 1px;
background: #f7f7f7;
}
.child {
margin-top: 20px; /* без padding у родителя может схлопнуться */
}
Частые ошибки и полезные советы
- Дублирование reset. Если подключаете CSS-фреймворк или normalize/reset, проверьте, не задаётся ли уже border-box глобально, чтобы не конфликтовать.
- outline не влияет на размер. В отличие от border, outline не участвует в расчёте ширины/высоты — удобно для hover/focus-состояний без «дёрганий» макета.
- min/max-width и высота. В border-box эти ограничения включают padding и border — учитывайте это в расчётах адаптивных карточек и модалок.
- Изображения и заменяемые элементы. box-sizing к ним применим, но не забывайте про их собственные особенности рендеринга (например, у img лучше добавить max-width: 100%; height: auto).
- Транзиции размеров. Анимировать width/height проще и предсказуемее, если padding/border уже внутри (border-box).
Мини‑практикум: адаптивная «шапка» с поиском
Соберём простую строку: логотип, поиск и кнопка. Благодаря border-box поиск растягивается ровно на доступное место и не уезжает при увеличении внутренних отступов.
/* Глобально */
html { box-sizing: border-box; }
*, *::before, *::after { box-sizing: inherit; }
.header {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
border-bottom: 1px solid #e0e0e0;
}
.logo { flex: 0 0 auto; }
.search {
flex: 1 1 auto;
display: flex;
}
.search input {
flex: 1 1 auto;
padding: 10px 14px;
border: 1px solid #cfd8dc;
border-radius: 6px;
box-sizing: border-box; /* избыточно, но явно */
}
.btn {
flex: 0 0 auto;
padding: 10px 14px;
border: 1px solid #1976d2;
background: #2196f3;
color: #fff;
border-radius: 6px;
}
<header class="header">
<div class="logo">Лого</div>
<div class="search">
<input type="search" placeholder="Найдите статью…">
</div>
<button class="btn">Войти</button>
</header>
Итоги
Используйте box-sizing: border-box по умолчанию для всего проекта — и вы получите стабильные сетки, предсказуемые размеры и меньше багов при доработках. Локально переключайтесь на content-box только когда это осознанно необходимо. Отлаживайте размеры через DevTools и не забывайте про схлопывание margin — это частый источник недоразумений у новичков.
Хотите быстрее прокачать практику вёрстки с нуля до уверенного уровня? Загляните на интенсив: Прокачать вёрстку на интенсиве «Вёрстка сайта с нуля 2.0» — много практики, разбор типичных ошибок и современные приёмы CSS.
-
Создано 23.03.2026 17:00:45
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.