Найти в Дзене
3 подписчика

Почему margin: 30px + margin: 20px иногда дают всего 30px?

Кажется логичным:

.first {
margin-bottom: 30px;
}

.second {
margin-top: 20px;
}

Между блоками должно получиться 50px.
Но в обычном потоке браузер может оставить всего 30px.
Это называется схлопывание margin.
Дело в том, что вертикальные внешние отступы обычных блочных элементов браузер не всегда воспринимает как две отдельные пустые области. Если эти margin соприкасаются, он может объединить их в один общий отступ.
Для двух положительных значений остаётся большее:

30px + 20px → 30px

Почему вообще так сделано?
Представь два абзаца: у первого есть margin-bottom, у второго — margin-top. Если всегда складывать оба значения, между текстовыми блоками легко получались бы огромные двойные отступы.
Поэтому CSS умеет их схлопывать.
Но это происходит не всегда. Обычно для схлопывания нужно, чтобы:
— элементы были обычными блочными элементами в normal flow;
— речь шла о вертикальных margin;
— между ними не было padding, border или другого содержимого.
Например, если добавить родителю:

.parent {
padding-top: 1px;
}

margin ребёнка уже не сможет напрямую «соприкоснуться» с margin родителя — и поведение изменится.
А во flex и grid margin между элементами вообще не схлопываются.
То есть странность не случайная: CSS объединяет соприкасающиеся вертикальные внешние отступы в обычном блочном потоке.
И если очередной margin вдруг будто «не работает» — возможно, он просто схлопнулся с соседним.
Почему margin: 30px + margin: 20px иногда дают всего 30px? Кажется логичным:  .first {   margin-bottom: 30px; }  .second {   margin-top: 20px; }  Между блоками должно получиться 50px.
1 минута