В каком случае схлопывание внешних отступов не сработает
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Схлопывание внешних отступов (Margin Collapse)
Что такое схлопывание
Margin collapse (схлопывание внешних отступов, коллапс маржинов) — это CSS механизм, при которой два соседних вертикальных margin объединяются в один, равный большему из двух.
Это может быть источником путанницы для новичков, потому что не всегда происходит так, как ожидается.
Пример схлопывания (что происходит)
<div class="box1">Box 1 (margin-bottom: 20px)</div>
<div class="box2">Box 2 (margin-top: 30px)</div>
.box1 {
margin-bottom: 20px;
}
.box2 {
margin-top: 30px;
}
Что вы ожидаете: расстояние между box1 и box2 = 20px + 30px = 50px
Что на самом деле: расстояние = 30px (берётся больший margin)
Когда происходит схлопывание
Маржины схлопываются только в следующих случаях:
1. Соседние блоки (adjacent siblings)
<p>Первый параграф (margin-bottom: 20px)</p>
<p>Второй параграф (margin-top: 30px)</p>
Маржины схлопываются: расстояние = 30px (больший)
2. Родитель и его первый/последний ребёнок
<div class="parent">
<p class="child">Абзац</p>
</div>
.parent {
margin-top: 20px;
}
.child {
margin-top: 10px;
}
Маржины схлопываются: margin-top parent = 20px (больший)
3. Пустые блоки
Если блок не имеет содержимого, его margin-top и margin-bottom схлопываются:
<div class="empty" style="margin-top: 20px; margin-bottom: 30px;"></div>
Итоговый margin = 30px (больший)
Когда схлопывание НЕ происходит
1. Горизонтальные маржины НИКОГДА не схлопываются
.box1 {
margin-right: 20px;
}
.box2 {
margin-left: 30px;
}
/* Расстояние = 20px + 30px = 50px (складываются, не схлопываются) */
2. При наличии border или padding у родителя
<div class="parent" style="border: 1px solid black;">
<p style="margin-top: 20px;">Абзац</p>
</div>
/* Маржин child НЕ схлопывается с маржином родителя
потому что у родителя есть border */
3. При наличии padding у родителя
<div class="parent" style="padding-top: 10px;">
<p style="margin-top: 20px;">Абзац</p>
</div>
/* Маржин child НЕ схлопывается
потому что у родителя есть padding */
4. Для элементов с overflow != visible
<div class="parent" style="overflow: auto;">
<p style="margin-top: 20px;">Абзац</p>
</div>
/* overflow: auto, hidden, scroll запрещает collapse */
5. Для flex и grid контейнеров
<div class="flex-container" style="display: flex;">
<p style="margin-top: 20px;">Элемент</p>
</div>
/* display: flex, grid, inline-flex, inline-grid
запрещают collapse маржинов */
6. Для inline и inline-block элементов
<span style="margin-top: 20px;">Текст</span>
/* display: inline НЕ поддерживает margin-top/bottom вообще
display: inline-block маржины НЕ схлопываются */
7. Для позиционированных элементов (absolute, fixed)
<div style="position: absolute; margin-top: 20px;">Текст</div>
/* position: absolute, fixed исключают element из обычного flow
маржины НЕ схлопываются */
8. Для float элементов
<div style="float: left; margin-top: 20px;">Текст</div>
/* float исключает элемент из обычного потока
маржины НЕ схлопываются */
Практические примеры
Пример 1: Две строки текста
<p style="margin-bottom: 20px;">Первая строка</p>
<p style="margin-top: 30px;">Вторая строка</p>
Результат: расстояние = 30px (большее значение)
Пример 2: Блок внутри контейнера
<div style="margin-top: 20px;"> <!-- Родитель -->
<h1 style="margin-top: 10px;">Заголовок</h1> <!-- Ребёнок -->
</div>
Результат: итоговый margin-top = 20px (большее значение)
Пример 3: Flex контейнер (collapse НЕ происходит!)
<div style="display: flex; margin-top: 20px;">
<p style="margin-top: 30px;">Абзац</p>
</div>
Результат: маржины НЕ схлопываются, потому что display: flex
Как избежать путаницы
Способ 1: Используй border или padding
.container {
padding-top: 1px; /* Блокирует collapse */
}
ребёнок {
margin-top: 20px; /* Теперь маржин не схлопывается */
}
Способ 2: Используй display: flex или grid
.container {
display: flex;
flex-direction: column;
}
/* Маржины детей НЕ схлопываются */
Способ 3: Используй gap вместо margin
.container {
display: flex;
flex-direction: column;
gap: 20px; /* Расстояние между элементами, не collapse */
}
Способ 4: Контролируй маржины явно
.box + .box {
margin-top: 20px; /* Применяется только ко второму и далее */
}
Резюме
Margin collapse НЕ происходит, если:
- Горизонтальные маржины (margin-left, margin-right)
- У родителя есть border
- У родителя есть padding
- Элемент в контейнере display: flex, grid, inline-flex, inline-grid
- Элемент позиционирован absolute или fixed
- Элемент плавает (float)
- Элемент inline или inline-block
- У элемента overflow != visible
В остальных случаях два вертикальных маржина схлопываются в один, равный большему из них.