Skip to Content
CSSБоксовая модель

Боксовая модель

Уровень: middle.

Вопрос

Из чего складывается ширина элемента и почему два соседних margin не суммируются?

Короткий ответ

Классическая модель content-box: width и height задают контент. Padding и border добавляются снаружи, итоговый размер больше заявленной ширины. border-box включает padding и border в width. В современных сбросах часто ставят box-sizing: border-box на все элементы, иначе сетка с паддингом вылезает из колонки.

Margin лежит уже вне border и в ширину по border-box не входит. Вертикальные margin соседей в обычном потоке схлопываются: остаётся больший, а не сумма. Горизонтальные не схлопываются. Схлопывание не происходит у flex- и grid-элементов, у float, и если между блоками есть padding, border или новый блок форматирования.

display: none убирает элемент из потока, места он не занимает. visibility: hidden место сохраняет, элемент невидим и не кликабелен. opacity: 0 место сохраняет, и элемент может ловить клики.

Разбор

Блок форматирования (BFC) создают, среди прочего, overflow, отличный от visible, display: flow-root, flex-контейнер, float. Внутри BFC вертикальные margin не выпадают наружу к родителю. Этим же лечат обтекание float: контейнер с BFC охватывает плавающие дети, иначе высота родителя схлопывается до нуля.

inline не принимает вертикальные margin и width так, как блок. inline-block строит бокс в строке и ширину принимает. Зазор между инлайн-блоками часто даёт пробел в HTML между тегами, не margin.

Процент у padding и margin считается от ширины содержащего блока, даже для вертикальных отступов. Высота в процентах требует явной высоты у родителя, иначе процент не от чего считать.

На что смотрят на senior

min-width: auto у flex-элемента не даёт колонке сжаться меньше контента. Длинное слово или картинка раздувают сетку, хотя у родителя задан max-width. Лечится min-width: 0 на ребёнке, которому разрешено сжиматься, плюс перенос или overflow.

Схлопывание margin у первого ребёнка с родителем двигает весь блок, хотя padding родителю не задавали. На макете это выглядит как «отступ прилип не туда».

Типичные ошибки

  • Ждать, что width: 100% плюс padding влезет в родителя при content-box.
  • Складывать вертикальные margin соседей в уме.
  • Путать display: none и visibility: hidden.
  • Ставить высоту в процентах внуку, у которого родительская высота auto.

Задача

У блока width: 200px, padding: 20px, border: 2px solid, box-sizing: content-box. Какая полная ширина на экране? Что изменится при border-box?

Показать ответ

При content-box ширина контента 200. По бокам padding 20 + 20 и border 2 + 2. Полная ширина 244px.

При border-box заявленные 200px уже включают padding и border. Контентная область станет уже, наружный размер останется 200px. Margin в обоих случаях снаружи и в width не входит.

Last updated on