Урок 7. Блочная модель — margin, padding, border
Для CSS каждый элемент страницы — прямоугольник, «коробка». От того, как устроена эта коробка, зависят все размеры и отступы на странице. Когда блок вдруг оказывается шире, чем задано, или отступ не тот, — дело почти всегда в блочной модели.
Из чего состоит блок
Изнутри наружу:
- Содержимое (content) — текст, картинка, вложенные элементы. Его размер задают
widthиheight. - Внутренний отступ (
padding) — поле между содержимым и рамкой. Фон блока заходит и под него. - Рамка (
border). - Внешний отступ (
margin) — расстояние до соседних элементов. Он всегда прозрачный.
.card {
width: 300px;
padding: 20px;
border: 2px solid #ccc;
margin: 16px;
background-color: #fafafa;
}Увидеть всё это на живой странице проще всего в инструментах разработчика: нажмите F12, выберите элемент — рядом со стилями будет схема блока с размерами содержимого, padding, border и margin.
Короткая запись отступов
margin и padding можно задать для каждой стороны отдельно (margin-top, margin-right, margin-bottom, margin-left) или одной строкой:
| Запись | Что значит |
|---|---|
padding: 10px; | со всех сторон 10px |
padding: 10px 20px; | сверху и снизу 10px, слева и справа 20px |
padding: 10px 20px 30px; | сверху 10px, слева и справа 20px, снизу 30px |
padding: 10px 20px 30px 40px; | сверху, справа, снизу, слева — по часовой стрелке |
Рамка тоже пишется одной строкой: толщина, вид линии, цвет — border: 1px solid black;. Вид линии бывает solid (сплошная), dashed (штрихи), dotted (точки). Рамка только с одной стороны — border-bottom: 1px solid black;. Скругление углов — border-radius: 8px;, круг из квадрата — border-radius: 50%;.
Сколько места занимает блок
По умолчанию width — это ширина только содержимого. Отступы и рамка прибавляются к ней. Блок .card выше займёт по ширине:
300 (содержимое) + 20 + 20 (padding) + 2 + 2 (border) = 344 пикселя — и ещё по 16 пикселей margin с каждой стороны.
Считать так неудобно: задали 300, получили 344. Свойство box-sizing: border-box меняет правило: width включает padding и рамку, и блок занимает ровно 300 пикселей, а под содержимое остаётся 300 − 40 − 4 = 256.
Почти все сайты включают такой расчёт для всех элементов сразу — поставьте эти строки в начало своего CSS:
*,
*::before,
*::after {
box-sizing: border-box;
}Блочные и строчные элементы
Свойство display определяет, как элемент ведёт себя среди соседей.
- Блочные (
display: block) —<div>,<p>,<h1>–<h6>,<ul>,<section>,<header>. Начинаются с новой строки и по умолчанию растягиваются на всю ширину родителя. Им можно задатьwidth,heightи любые отступы. - Строчные (
display: inline) —<span>,<a>,<strong>,<em>. Идут внутри строки текста, как слова.widthиheightна них не действуют, аmarginиpaddingсверху и снизу не раздвигают строки. - Строчно-блочные (
display: inline-block) — стоят в строке, как слово, но принимают размеры и отступы, как блок. Так делают, например, кнопку из ссылки.
display можно поменять у любого элемента: ссылке — display: block, пункту списка — display: inline. display: none убирает элемент со страницы совсем. Ещё два значения — flex и grid — тема следующих уроков.
Ширина: width и max-width
.page {
max-width: 960px;
margin: 0 auto;
padding: 0 16px;
}max-width: 960px— блок не шире 960 пикселей, но на узком экране сужается вместе с окном. С обычнымwidth: 960pxна телефоне появилась бы прокрутка вбок.margin: 0 auto— сверху и снизу 0, а слева и справа браузер делит свободное место поровну: блок встаёт по центру. Так центрируют основную колонку почти любого сайта. Это работает только у блока, ширина которого меньше родителя.padding: 0 16px— текст не прилипает к краям экрана на телефоне.
Высоту обычно не задают: блок сам растёт по содержимому. Жёсткая height приводит к тому, что длинный текст вылезает за край. Если нужна наименьшая высота — min-height.
Отступы по умолчанию
Браузер сам даёт отступы некоторым элементам: у body — 8 пикселей со всех сторон, у <p> и заголовков — сверху и снизу, у списков — слева. Из-за этого страница никогда не прилегает к краю окна. Если это мешает, обнулите:
body {
margin: 0;
}Схлопывание внешних отступов
Вертикальные margin соседних блоков не складываются, а схлопываются: между абзацем с margin-bottom: 20px и абзацем с margin-top: 30px будет 30 пикселей, а не 50 — побеждает больший. Горизонтальные отступы и padding так себя не ведут.
Ещё один случай: margin-top первого вложенного элемента может «вылезти» наружу и сдвинуть вниз весь родительский блок. Помогает padding-top у родителя вместо margin-top у ребёнка. Внутри Flexbox и Grid отступы не схлопываются.
Частые ошибки
- Блок шире, чем задано, появилась прокрутка вбок — к
width: 100%прибавились padding и рамка. Включитеbox-sizing: border-box. margin: 0 autoне центрирует — у блока нет ширины меньше родителя (он и так на всю ширину) или это строчный элемент. Задайтеmax-widthиdisplay: block.- Ширина у ссылки или
<span>не меняется — строчный элемент. Поставьтеdisplay: inline-block. - Отступ между блоками меньше, чем ожидалось — сработало схлопывание margin.
Коротко
- Блок — это содержимое,
padding,borderиmarginизнутри наружу. - Короткая запись: одно значение — со всех сторон, два — вертикаль и горизонталь, четыре — по часовой стрелке от верха.
box-sizing: border-boxдля всех элементов:widthвключает отступы и рамку.- Блочные элементы занимают всю ширину, строчные идут в тексте и не принимают
widthиheight. - Основная колонка:
max-widthиmargin: 0 auto. - Вертикальные margin соседних блоков схлопываются: остаётся больший.