Из чего состоит коробка
Каждый элемент в CSS это прямоугольник из четырёх слоёв изнутри наружу:
- content: содержимое, его размер задают
widthиheight; - padding: внутренний отступ, закрашивается фоном элемента;
- border: рамка;
- margin: внешний отступ, всегда прозрачный.
box-sizing
По умолчанию box-sizing: content-box: width задаёт только content, а padding и border прибавляются сверху.
.card {
width: 200px;
padding: 20px;
border: 5px solid;
}
/* content-box: итоговая ширина 200 + 20*2 + 5*2 = 250px */
/* border-box: итоговая ширина 200px, content = 200 - 40 - 10 = 150px */
При box-sizing: border-box в width входят content, padding и border. Margin не входит никогда. Почти все проекты начинают со сброса:
*, *::before, *::after { box-sizing: border-box; }
Схлопывание margin
Вертикальные margin соседних блоков в обычном потоке не складываются, а схлопываются: берётся больший.
.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
/* между .a и .b будет 30px, а не 50px */
Также margin первого ребёнка может «вытечь» наружу родителя, если между ними нет padding, border или нового контекста форматирования.
Схлопывания нет:
- у горизонтальных margin;
- у flex- и grid-элементов;
- у элементов с
floatиposition: absolute; - если родитель создаёт новый блочный контекст форматирования (BFC), например
display: flow-root,overflowкромеvisible; тогда margin ребёнка не вытекает из родителя.
Отрицательный и положительный margin при схлопывании суммируются: 30px и -10px дают 20px.
display: внешний и внутренний тип
block: занимает всю доступную ширину, начинается с новой строки, уважаетwidth,height, вертикальные margin.inline: течёт в строке как текст.widthиheightигнорирует, вертикальные margin не сдвигают соседей, вертикальный padding рисуется, но строки не раздвигает.inline-block: стоит в строке, но внутри ведёт себя как блок, размеры работают.none: элемента нет в раскладке и в дереве доступности.flex,grid: снаружи блок, внутри своя раскладка детей.inline-flex,inline-grid: снаружи строчный.flow-root: блок, который создаёт новый BFC. Заменяет старый clearfix для float.contents: коробки элемента нет, его дети встают на его место в раскладке.
Проценты и auto
width: 100%это 100% ширины content-области родителя. Сcontent-boxи padding элемент вылезет за родителя, отсюда популярностьborder-box.- Процентный
paddingиmargin, даже вертикальные, считаются от ширины родителя. - Процентная
heightработает, только если высота родителя задана явно (или элемент в grid/flex с растяжением). margin: 0 autoу блока с заданной шириной центрирует его по горизонтали.
Переполнение
overflow: visible | hidden | clip | scroll | auto. auto показывает скролл только при необходимости. hidden обрезает, но элемент всё ещё прокручивается программно; clip обрезает без возможности прокрутки и не создаёт контейнер прокрутки.
Высоту, которая подстраивается под содержимое в рамках границ, задают через min-height и max-height, а не жёсткую height, иначе текст вылезет.
Пропорции: aspect-ratio
.video { width: 100%; aspect-ratio: 16 / 9; }
Свойство aspect-ratio поддерживается всеми современными браузерами и заменило старый трюк с padding-top: 56.25%.
Логические свойства
margin-inline, padding-block, inset-inline-start, inline-size описывают стороны относительно направления текста. В обычном горизонтальном письме слева направо margin-inline-start равен margin-left, а в арабском (rtl) станет margin-right. margin-inline: auto центрирует блок.
Частые ошибки
- Забыть
border-boxи получить вылезающий на 2px блок. - Ждать 50px между блоками с margin 30 и 20.
- Задать
widthстрочному<span>и удивиться, что не работает. - Задать процентную высоту при родителе с
height: auto.
Что спросят на собесе
- Из чего состоит блочная модель и чем
content-boxотличается отborder-box. - Посчитай итоговую ширину блока.
- Что такое схлопывание margin и как его избежать.
- Чем
inline,blockиinline-blockотличаются по поведению. - От чего считаются процентные padding и margin.