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 вдруг будто «не работает» — возможно, он просто схлопнулся с соседним.
1 минута
31 августа