Урок 4 из 49 · Месяц 1. HTML5 и CSS3
Позиционирование, единицы измерения и блочная модель
Содержание урока
- Блочная модель
- padding — внутренний отступ
- margin — внешний отступ
- Особенности margin
- border — рамка
- border-radius — скругление углов
- box-sizing: как считается ширина
- Единицы измерения
- px — пиксели
- % — проценты
- em — относительно шрифта элемента
- rem — относительно корня
- Когда что использовать
- position — позиционирование
- static — по умолчанию
- relative — сдвиг относительно своего места
- absolute — точно в нужной точке родителя
- fixed — приклеен к окну
- sticky — прилипает при прокрутке
- z-index — кто сверху
- Сводная таблица
- Типичные ошибки
- Практика
- Итоги
Каждый элемент на странице — это прямоугольная коробка, и умение управлять её размерами, отступами и положением отличает аккуратную вёрстку от «поехавшей». В этом уроке разберём блочную модель (margin, padding, border, border-radius), единицы измерения px, %, em и rem и свойство position, которое позволяет точно ставить элементы туда, куда нужно.
Блочная модель
Браузер рисует любой элемент как прямоугольник из четырёх слоёв — от центра к краю:
┌──────────────── margin (внешний отступ) ────────────────┐
│ ┌──────────────── border (рамка) ──────────────────┐ │
│ │ ┌──────────── padding (внутренний отступ) ───┐ │ │
│ │ │ │ │ │
│ │ │ content (содержимое) │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Аналогия — картина в раме на стене:
- content — сама картина;
- padding — паспарту, белое поле между картиной и рамой;
- border — рамка;
- margin — расстояние от рамы до соседних картин.
Посмотреть блочную модель любого элемента можно в DevTools: Elements → справа вкладка Computed — там нарисована именно такая схема с реальными числами.
padding — внутренний отступ
padding отодвигает содержимое от краёв элемента внутрь. Фон элемента закрашивает и padding.
.button {
background-color: #2b6cb0;
color: white;
padding: 12px 24px;
}
У padding (и у margin) есть четыре стороны, и записать их можно по-разному:
.box {
padding: 20px; /* все четыре стороны */
padding: 10px 20px; /* верх-низ 10, лево-право 20 */
padding: 10px 20px 30px; /* верх 10, лево-право 20, низ 30 */
padding: 10px 20px 30px 40px; /* верх, право, низ, лево */
}
Четыре значения идут по часовой стрелке, начиная сверху: верх → право → низ → лево. Можно задать и одну сторону:
.box {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
}
margin — внешний отступ
margin отталкивает элемент от соседей. Он всегда прозрачный — фон на него не распространяется. Сокращения те же, что у padding.
.card {
margin-bottom: 24px; /* отступ до следующей карточки */
}
.container {
width: 960px;
margin: 0 auto; /* центрирование блока по горизонтали */
}
margin: 0 auto — классический способ поставить блок с заданной шириной по центру: сверху и снизу 0, а слева и справа браузер сам распределяет свободное место поровну.
Особенности margin
- Отрицательные значения допустимы:
margin-top: -20pxподтягивает элемент вверх. - Схлопывание: вертикальные margin соседних блоков не складываются, а берётся больший. Если у одного абзаца
margin-bottom: 20px, а у следующегоmargin-top: 30px, расстояние между ними будет 30px, а не 50px. - Браузер сам добавляет отступы некоторым тегам (
body,h1,p,ul). Поэтому вёрстку часто начинают со сброса:
body {
margin: 0;
}
h1, h2, p, ul {
margin-top: 0;
}
border — рамка
.card {
border: 1px solid #ddd;
}
Сокращение border принимает три значения: толщина, стиль, цвет. Стиль обязателен — без него рамки не будет.
| Стиль | Вид |
|---|---|
solid |
Сплошная линия |
dashed |
Штрихи |
dotted |
Точки |
double |
Двойная линия |
none |
Нет рамки |
Можно задать рамку только с одной стороны:
.tab {
border-bottom: 3px solid tomato; /* подчёркивание активной вкладки */
}
.quote {
border-left: 4px solid #2b6cb0; /* полоска слева у цитаты */
padding-left: 16px;
}
border-radius — скругление углов
.card { border-radius: 12px; } /* все углы */
.pill { border-radius: 999px; } /* «таблетка» — кнопка с круглыми краями */
.avatar {
width: 80px;
height: 80px;
border-radius: 50%; /* квадрат становится кругом */
}
.tag { border-radius: 8px 0 8px 0; } /* углы по часовой с левого верхнего */
border-radius работает даже без рамки — скругляются фон и картинка.
box-sizing: как считается ширина
Вопрос: какой ширины будет этот блок на экране?
.box {
width: 200px;
padding: 20px;
border: 5px solid black;
}
По умолчанию (box-sizing: content-box) width — это ширина только содержимого. Padding и border прибавляются сверху: 200 + 20·2 + 5·2 = 250px. Это неудобно: задали 200, а получили 250.
Со значением border-box ширина включает padding и border — блок будет ровно 200px, а под содержимое останется 150px. Поэтому почти все проекты начинают с такого правила:
*,
*::before,
*::after {
box-sizing: border-box;
}
Единицы измерения
px — пиксели
Абсолютная единица: 16px — всегда 16 пикселей. Просто и предсказуемо. Хороши для рамок, мелких деталей и теней.
.card { border: 1px solid #ddd; }
% — проценты
Считаются от родителя. Для width — от ширины родителя, для font-size — от размера шрифта родителя.
.parent { width: 800px; }
.child { width: 50%; } /* 400px */
Обратите внимание: padding и margin в процентах считаются от ширины родителя — даже вертикальные.
em — относительно шрифта элемента
1em = текущий font-size элемента. Если у элемента 20px, то 1em = 20px, 0.5em = 10px. Удобно, когда отступ должен расти вместе с текстом:
.button {
font-size: 18px;
padding: 0.5em 1em; /* 9px 18px — пропорционально шрифту */
}
Ловушка em — накопление. Если font-size указан в em, он считается от шрифта родителя, и при вложенности умножается:
<div class="level">Уровень 1
<div class="level">Уровень 2
<div class="level">Уровень 3</div>
</div>
</div>
.level { font-size: 1.2em; }
/* при базовых 16px: 19.2px → 23.04px → 27.65px */
rem — относительно корня
rem (root em) считается от размера шрифта корневого элемента <html>. По умолчанию в браузерах это 16px, значит 1rem = 16px, 1.5rem = 24px, 0.75rem = 12px. Никакого накопления — везде одинаково.
h1 { font-size: 2.5rem; } /* 40px */
p { font-size: 1rem; } /* 16px */
.section { margin-bottom: 3rem; } /* 48px */
Главный плюс rem: если пользователь увеличит размер шрифта в настройках браузера, все размеры в rem увеличатся пропорционально. Это важно для людей со слабым зрением.
Когда что использовать
| Единица | От чего считается | Где удобна |
|---|---|---|
px |
Ни от чего, абсолютная | Рамки, тени, мелкие детали |
% |
Родитель | Ширина блоков и колонок |
em |
Шрифт самого элемента | Отступы внутри кнопок и бейджей |
rem |
Шрифт <html> |
Размеры шрифтов, общие отступы |
Есть ещё vw и vh — 1% ширины и высоты окна браузера. Например, height: 100vh — блок на весь экран.
position — позиционирование
По умолчанию элементы идут в нормальном потоке: блочные — сверху вниз, строчные — слева направо. Свойство position позволяет вынуть элемент из этого порядка или сдвинуть его. Вместе с ним используют top, right, bottom, left — смещения от краёв.
static — по умолчанию
.box { position: static; }
Элемент стоит в обычном потоке, а top/left на него не действуют. Писать static явно почти никогда не нужно.
relative — сдвиг относительно своего места
.badge {
position: relative;
top: -5px;
left: 10px;
}
Элемент визуально сдвигается на 5px вверх и на 10px вправо, но его место в потоке остаётся — соседи не двигаются, как будто он стоит на прежнем месте. Главное применение relative — служить точкой отсчёта для absolute.
absolute — точно в нужной точке родителя
<div class="card">
<span class="card-badge">NEW</span>
<h3>Капучино</h3>
</div>
.card {
position: relative; /* точка отсчёта */
width: 300px;
padding: 24px;
border: 1px solid #ddd;
border-radius: 12px;
}
.card-badge {
position: absolute;
top: 12px;
right: 12px;
padding: 4px 8px;
background-color: tomato;
color: white;
border-radius: 6px;
}
absoluteвынимает элемент из потока: остальные ведут себя так, будто его нет.- Координаты считаются от ближайшего предка, у которого
positionнеstatic(обычно ставятrelative). Здесь это.card, поэтому бейдж стоит в её правом верхнем углу. - Если такого предка нет, отсчёт идёт от всей страницы — и бейдж «улетит» в угол экрана.
fixed — приклеен к окну
.to-top {
position: fixed;
right: 24px;
bottom: 24px;
}
Элемент отсчитывается от окна браузера и не двигается при прокрутке. Так делают кнопки «наверх», чаты поддержки, плавающие панели.
sticky — прилипает при прокрутке
.header {
position: sticky;
top: 0;
background-color: white;
}
Пока страница не прокручена, шапка стоит на своём месте. Когда при прокрутке её верх доходит до top: 0, она «прилипает» к краю окна и едет вместе с ним — но только в пределах своего родителя.
z-index — кто сверху
Позиционированные элементы могут перекрывать друг друга. Порядок слоёв задаёт z-index: чем больше число, тем выше слой.
.modal { position: fixed; z-index: 100; }
.header { position: sticky; z-index: 10; }
z-index работает только у элементов с position, отличным от static (а также у элементов внутри flex-контейнера).
Сводная таблица
| Значение | В потоке? | От чего отсчёт | Пример |
|---|---|---|---|
static |
Да | — | Обычный текст |
relative |
Да (место сохраняется) | Своё обычное место | Родитель для absolute |
absolute |
Нет | Ближайший позиционированный предок | Бейдж на карточке |
fixed |
Нет | Окно браузера | Кнопка «наверх» |
sticky |
Да, пока не прилип | Окно при прокрутке | Липкая шапка |
Типичные ошибки
- Ширина «не сходится», блоки вылезают — забыли
box-sizing: border-box. - Нет рамки при
border: 2px red— не указан стиль (solid). - Огромный текст во вложенных блоках — накопление
em; для шрифтов беритеrem. margin: 0 autoне центрирует — у блока не задана ширина или это строчный элемент.absolute-элемент улетел — у родителя нетposition: relative.
Справочник по свойству — MDN: position.
Практика
- Кнопка. Сделайте ссылку-кнопку: фон, белый текст,
padding: 0.75em 1.5em,border-radius: 8px, без подчёркивания. Результат: аккуратная кнопка; при увеличенииfont-sizeотступы растут пропорционально. - Карточки. Сверстайте три карточки одна под другой: белый фон,
padding: 1.5rem, рамка1px solid #ddd, скругление 12px, расстояние между ними1.5rem. Результат: карточки не слипаются, текст не прилипает к краям. - Аватар. Квадратный блок 100×100px с фоном превратите в круг и поставьте по центру страницы через
margin: 0 auto. Результат: круг по центру. - Бейдж и кнопка «наверх». Добавьте карточке бейдж «SALE» в правом верхнем углу через
absolute, а на страницу — кнопку «Наверх» сposition: fixedв правом нижнем углу. Результат: бейдж держится за карточку, кнопка не уезжает при прокрутке. - Липкая шапка. Сделайте длинную страницу (много абзацев) и шапку с
position: sticky; top: 0. Результат: при прокрутке шапка остаётся вверху и не прячется под текстом (подберитеz-indexи фон).
Итоги
- Каждый элемент — коробка: content → padding → border → margin.
- Сокращения padding/margin идут по часовой стрелке: верх, право, низ, лево.
box-sizing: border-boxделаетwidthполной шириной элемента — ставьте его всегда.px— абсолютно,%— от родителя,em— от шрифта элемента,rem— от шрифта<html>.relativeсдвигает и служит точкой отсчёта,absoluteставит точно внутри родителя.fixedприклеивает к окну,sticky— прилипает при прокрутке,z-indexуправляет слоями.