Box model: margin, padding, border
Что такое box model
Box model — модель, по которой браузер рассчитывает размеры каждого элемента.
Уровни (снаружи внутрь):
margin → border → padding → content
Что означает:
content— само содержимое (текст, картинка).padding— внутренние отступы (между содержимым и рамкой).border— рамка.margin— внешние отступы (между элементами).
content-box vs border-box
По умолчанию (content-box):
.box {
width: 200px;
padding: 20px;
border: 2px solid black;
/* итоговая ширина: 200 + 40 + 4 = 244px */
}
border-box:
*, *::before, *::after {
box-sizing: border-box;
}
.box {
width: 200px;
padding: 20px;
border: 2px solid black;
/* итоговая ширина: 200px (padding и border внутри) */
}
Правило: всегда border-box. Это стандарт.
padding
Со всех сторон:
padding: 16px;
Вертикаль / горизонталь:
padding: 16px 24px; /* top-bottom 16, left-right 24 */
Сверху / горизонталь / снизу:
padding: 8px 16px 24px;
Все четыре:
padding: 8px 16px 24px 32px; /* top right bottom left (по часовой) */
Отдельно:
padding-top: 16px;
padding-right: 24px;
padding-bottom: 16px;
padding-left: 24px;
Правило: padding не может быть отрицательным.
margin
Синтаксис такой же:
margin: 16px;
margin: 8px 16px;
margin: 8px 16px 24px;
margin: 8px 16px 24px 32px;
Отдельно:
margin-top: 16px;
margin-inline: 24px; /* left + right (логические свойства) */
margin-block: 16px; /* top + bottom */
Отрицательные:
margin-top: -8px; /* ок */
Правило: margin может быть отрицательным.
Схлопывание margin
Вертикальные margin соседних блоков схлопываются:
<p style="margin-bottom: 20px">Первый</p>
<p style="margin-top: 30px">Второй</p>
Отступ между ними: не 50px, а 30px (максимум из двух).
Когда схлопываются:
- Соседние вертикальные margin.
- Родителя и первого ребёнка (если нет padding/border между ними).
- Родителя и последнего ребёнка.
Как избежать:
.parent {
padding-top: 1px; /* или */
border-top: 1px solid transparent; /* или */
overflow: hidden; /* создаст BFC */
display: flow-root; /* современный способ */
}
Правило: используйте gap во flex/grid вместо margin — нет схлопывания.
margin и padding: когда что
padding — внутри:
- Отступ от текста до рамки.
- Кнопки, карточки.
margin — снаружи:
- Расстояние между элементами.
- Отступ секции.
Правило: внутри — padding. Снаружи — margin (или gap).
border
border: 1px solid #e5e5e5;
/* Отдельно */
border-width: 1px;
border-style: solid;
border-color: #e5e5e5;
/* Сторона */
border-top: 2px dashed red;
border-bottom: 1px solid #000;
Стили:
solid— сплошная.dashed— пунктир.dotted— точки.double— двойная.none— нет.
Правило: border: 1px solid — дефолт. Для акцента — 2px.
border-radius
border-radius: 8px;
border-radius: 50%; /* круг */
border-radius: 8px 0 8px 0; /* углы по часовой */
border-radius: 999px; /* пилюля */
Правило: 4-8px для современного вида. 50% — для круглых аватаров.
outline
outline: 2px solid blue;
outline-offset: 2px;
Отличие от border:
- Не занимает места в box model.
- Не влияет на layout.
- Не скругляется с
border-radius(в старых браузерах).
Правило: outline — для фокуса. Не убирать!
:focus-visible {
outline: 2px solid #c1442e;
outline-offset: 2px;
}
box-shadow
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
/* x y blur spread color */
box-shadow: 0 1px 2px #000; /* маленькая */
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); /* средняя */
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); /* большая */
/* Внутренняя */
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
/* Несколько теней */
box-shadow:
0 1px 2px rgba(0,0,0,0.05),
0 4px 8px rgba(0,0,0,0.05);
Правило: тень — мягкая, многослойная, полупрозрачная.
Логические свойства
Вместо margin-top — margin-block-start:
margin-block-start: 16px; /* top или bottom в RTL */
margin-inline-end: 24px; /* right или left в RTL */
padding-block: 8px 16px; /* top / bottom */
padding-inline: 16px 24px; /* left / right */
Что даёт: работает для RTL-языков (арабский, иврит).
Правило: использовать для международных проектов.
Сброс стилей
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Что даёт: убирает дефолтные отступы браузера.
Пример: карточка
.card {
box-sizing: border-box;
padding: 24px;
margin-bottom: 16px;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 10px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.card:hover {
border-color: #c1442e;
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
}
.card__title {
margin: 0 0 8px;
font-size: 1.25rem;
}
.card__text {
margin: 0;
color: #6b6b6b;
}
Практика
1. Создайте карточку с padding, border, radius, shadow.
2. Попробуйте border-box vs content-box — проверьте ширину.
3. Схлопывание margin:
<div style="margin-bottom: 20px">A</div>
<div style="margin-top: 30px">B</div>
Проверьте в DevTools — расстояние 30px.
4. Кнопка с padding, border, radius, hover.
5. Фокус через :focus-visible.
Частые ошибки
1. content-box по умолчанию:
Ширина не такая, как ожидалось
Решение: box-sizing: border-box.
2. margin: 0 auto для центрирования блока:
Работает, но требует width меньше 100%.
Решение: flex/grid.
3. Схлопывание margin:
Ожидал 50px, получил 30px
Решение: gap или flow-root.
4. outline: none:
Не видно фокуса
Решение: :focus-visible.
5. border добавляет ширину:
1200px + border = 1204px
Решение: border-box.
6. padding для вертикального выравнивания:
Хрупко
Решение: flex align-items: center.
7. Огромный margin сверху у первого элемента:
Схлопывание с body
Решение: padding у родителя.
8. box-shadow без rgba:
box-shadow: 0 2px 8px #000; /* жёстко */
Решение: rgba(0,0,0,0.1).
Итог
- Box model: margin → border → padding → content.
border-box— всегда.padding— внутри,margin— снаружи.- Схлопывание margin — вертикальное.
border: 1px solid— дефолт.border-radius— 4-8px или 999px.box-shadow— мягкая, rgba.outline— для фокуса, не убирать.- Логические свойства — для RTL.
Дальше — display, position, z-index.