Схлопывание margin как исправить

Вертикальные margin у соседних элементов объединяются между собой, что известно под термином «схлопывающиеся margin». Само схлопывание действует на два соседних блока или родительский и дочерний блоки, при этом примыкающие отступы не суммируются, а комбинируются в один.

Для margin слева и справа схлопывание никогда не применяется.

Схлопывание margin у соседних элементов

Схлопывание задумывалось в первую очередь для корректного отображения текста в абзацах. Расстояние между абзацами <p> без схлопывания увеличится в два раза, тогда как верхний margin у первого абзаца и нижний margin у последнего абзаца останутся неизменными. Схлопывание гарантирует, что расстояние в абзацах везде будет одинаковым.

В примере 1 два блока располагаются один под другим, при этом у первого блока отступ снизу равен 20px, а у второго блока отступ сверху равен 10px.

Пример 1. Схлопывание margin

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.block {
padding: 20px; /* Поля вокруг текста */
border: 1px solid #666; /* Параметры рамки */
}
.block1 {
background: #E2EDC1; /* Цвет фона первого блока */
margin-bottom: 20px; /* Отступ снизу */
}
.block2 {
background: #FCE3EE; /* Цвет фона второго блока */
margin-top: 10px; /* Отступ сверху */
}
</style>
</head>
<body>
<div class=»block block1″>Первый блок</div>
<div class=»block block2″>Второй блок</div>
</body>
</html>

Результат данного примера показан на рис. 1. Расстояние между двумя блоками будет равно не 30 пикселей, как многие ожидают, а 20 пикселей, потому что выбирается большее значение из двух margin.

Вертикальное расстояние между блоков

Рис. 1. Вертикальное расстояние между блоков

Если оба значения margin положительные, то из них выбирается наибольшее значение и оно задаётся как расстояние между блоков.

На рис. 2 приведено схематическое изображение результата схлопывания margin.

Схлопывание margin

Рис. 2. Схлопывание margin

Если один из margin отрицательный, то в этом случае происходит их складывание по правилам математики:

x + (-y) = x – y

Если один из margin отрицательный, тогда margin вычитаются.

На рис. 3 схематично приведено поведение блоков, когда верхний margin у нижнего блока отрицательный.

Один margin отрицательный

Рис. 3. Один margin отрицательный

Если полученное значение в результате суммирования окажется отрицательным, то оно будет действовать на нижний блок, соответственно, он сдвинется вверх на указанное значение. При этом возможно наложение одного блока на другой. В примере 2 показан блок с верхним отрицательным margin.

Пример 2. Отрицательный margin

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.block {
padding: 20px; /* Поля вокруг текста */
border: 1px solid #666; /* Параметры рамки */
}
.block1 {
background: #E2EDC1; /* Цвет фона первого блока */
margin-bottom: 20px; /* Отступ снизу */
}
.block2 {
background: #FCE3EE; /* Цвет фона второго блока */
margin-top: -10px; /* Отрицательный отступ сверху */
}
</style>
</head>
<body>
<div class=»block block1″>Первый блок</div>
<div class=»block block2″>Второй блок</div>
</body>
</html>

Результат данного примера показан на рис. 4. Расстояние между двумя блоками считается как отступ снизу у верхнего блока минус отступ сверху у нижнего блока (20px-10px). В итоге расстояние будет равно 10 пикселей.

Вертикальное расстояние между блоков

Рис. 4. Вертикальное расстояние между блоков

Если оба margin отрицательные, то из двух значений выбирается наибольшее по модулю, оно же и выступает в качестве отрицательного отступа между элементами.

Так, если отступы равны -10px и -20px, то итоговое значение будет -20px. При этом элементы будут частично перекрываться (рис. 5).

Отрицательные margin

Рис. 5. Отрицательные margin

Пустые элементы

Для пустых элементов, внутри которых нет никакого содержимого, margin-top и margin-bottom также комбинируются в один по тем же правилам, что и для соседних блоков. При этом должен ещё соблюдаться ряд условий:

  • для элемента не должен быть задан padding сверху или снизу;
  • для элемента не должен быть задан border сверху или снизу;
  • высота элемента не должна быть указана через свойство height или min-height.

Одновременное сочетание всех этих условий (нет содержимого, не указана высота, padding и border) встречается довольно редко, так что многие веб-разработчики никогда и не сталкиваются с подобным поведением. В примере 3 пустой блок применяется в качестве разделителя между цветными блоками.

Пример 3. Пустой блок

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.hollow {
margin-top: 20px; /* Отступ сверху */
margin-bottom: 20px; /* Отступ снизу */
}
.block {
padding: 20px; /* Поля вокруг текста */
border: 1px solid #666; /* Параметры рамки */
}
.block1 {
background: #E2EDC1; /* Цвет фона первого блока */
}
.block2 {
background: #FCE3EE; /* Цвет фона второго блока */
}
</style>
</head>
<body>
<div class=»block block1″>Первый блок</div>
<div class=»hollow»></div>
<div class=»block block2″>Второй блок</div>
</body>
</html>

Результат данного примера показан на рис. 6. Расстояние между двумя цветными блоками определяется пустым блоком с классом hollow. У этого блока верхний и нижний margin объединяются в один, общая высота которого будет 20 пикселей.

Схлопывание margin у пустого блока

Рис. 6. Схлопывание margin у пустого блока

Вложенные элементы

Также схлопываются margin самого блока с margin у его первого и последнего дочерними элементами. Более точно комбинируется так:

  • margin-top родителя с margin-top его первого дочернего элемента;
  • margin-bottom родителя с margin-bottom его последнего дочернего элемента.

На рис. 7 схематично показано что margin у дочернего элемента располагается не внутри родителя, а выходит за его пределы.

margin у дочернего элемента

Рис. 7. margin у дочернего элемента

Такое поведение часто можно встретить у заголовков, вроде <h1> или <h2>, которые идут первыми в блоке. У этих заголовков уже содержится margin-top и margin-bottom по умолчанию и он, объединяясь с родительским margin, влияет на отступы всего блока (пример 4).

Пример 4. margin у заголовка

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.block {
background: #FCE3EE; /* Цвет фона блока */
}
h1 {
background: #E2EDC1; /* Цвет фона заголовка */
}
</style>
</head>
<body>
<div class=»block»>
<h1>Заголовок</h1>
</div>
<p>Текст снизу</p>
</body>
</html>

Результат данного примера показан на рис. 8. margin у <h1> выходит за пределы блока и задаёт внешние отступы до и после блока.

margin у дочернего элемента

Рис. 8. margin у дочернего элемента

Отмена схлопывания margin

Схлопывание не всегда требуется при вёрстке страницы, а в некоторых случаях вообще «ломает» дизайн. Поэтому следует знать, в каких случаях схлопывание не работает.

Схлопывание margin не срабатывает:

  • для элементов с абсолютным позиционированием, т. е. таких, у которых position установлено как absolute или fixed;
  • для обтекаемых элементов (для них свойство float задано как left или right);
  • для строчных или строчно-блочных элементов (для них свойство display задано как inline или inline-block);
  • для флекс-элементов (у родителя которых свойство display задано как flex или inline-flex);
  • для элемента <html>.

Схлопывание не действует на дочерние элементы:

  • если у родителя значение overflow задано как auto, hidden или scroll;
  • если у родителя на стороне схлопывания задано свойство padding;
  • если у родителя на стороне схлопывания задано свойство border.

Учтите, что свойства padding и border должны иметь размер больше нуля, к примеру, 1px.

Возьмём пример 4 и доработаем его, чтобы margin у заголовка работал внутри блока. Для этого к родительскому блоку добавляем свойство padding со значением 0.1px. На экране такая величина будет незаметна, но браузеры её понимают и схлопывание margin отменяют (пример 5).

Пример 5. Отмена схлопывания margin

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.block {
background: #FCE3EE; /* Цвет фона блока */
padding: 0.1px 0; /* Отменяем схлопывание */
}
h1 {
background: #E2EDC1; /* Цвет фона заголовка */
}
</style>
</head>
<body>
<div class=»block»>
<h1>Заголовок</h1>
</div>
<p>Текст снизу</p>
</body>
</html>

Результат данного примера показан на рис. 9.

margin у дочернего элемента

Рис. 9. margin у дочернего элемента

Для отмены схлопывания у дочерних элементов можно использовать один из вариантов.

.block {
  /* 1. Ненулевой padding сверху и снизу */ 
  padding: 0.1px 0;
  /* 2. Скрываем всё за пределами блока */ 
  overflow: hidden;
  /* 3. Прозрачная линия сверху и снизу */
  border-top: 1px solid transparent; 
  border-bottom: 1px solid transparent;
}

Для соседних элементов схлопывание margin отменять, как правило, нет необходимости, поскольку результат достаточно предсказуем — надо только помнить о поведении margin или включать margin-top или margin-bottom лишь для одного элемента. В примере 6 расстояние между блоков регулируется значением margin-bottom у block1. Здесь этот margin единственный, поэтому никакого объединения не происходит и вертикальный промежуток между блоков равен значению margin-bottom.

Пример 6. Расстояние между блоков

<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>margin</title>
<style>
.block {
padding: 20px; /* Поля вокруг текста */
border: 1px solid #666; /* Параметры рамки */
}
.block1 {
background: #E2EDC1; /* Цвет фона первого блока */
margin-bottom: 30px; /* Отступ снизу */
}
.block2 {
background: #FCE3EE; /* Цвет фона второго блока */
}
</style>
</head>
<body>
<div class=»block block1″>Первый блок</div>
<div class=»block block2″>Второй блок</div>
</body>
</html>

Для полноты картины приведём несколько вариантов, когда схлопывание margin у соседних блоков не работает. Данный стиль можно добавить к каждому блоку или только к одному. Ширина элемента с float определяется содержимым элемента, поэтому надо явно задать ширину блока, равную 100%. За счёт этого не ломается вёрстка, потому что нет места для обтекания элемента.

/* 1. Использование float */
.block {
  float: left; /* Обтекаемый элемент */
  width: 100%; /* Занимает всю доступную ширину */
  box-sizing: border-box; /* Ширина не учитывает padding и border */
}

Ширина строчно-блочных элементов также определяется их содержимым, поэтому данный вариант похож на предыдущий.

/* 2. Использование строчно-блочных элементов */
.block {
  display: inline-block; /* Строчно-блочный элемент */
  width: 100%; /* Занимает всю доступную ширину */
  box-sizing: border-box; /* Ширина не учитывает padding и border */
}

Класс parent надо добавить к родителю наших блоков.

/* 3. Использование флексбоксов */
.parent {
  display: flex; /* Работаем с флексами */
  flex-direction: column; /* Элементы выводятся друг под другом */
}

Перейти к заданиям

Последнее изменение: 31.05.2020

Победа над неочевидным. Схлопывание внешних отступов

Время на прочтение
5 мин

Количество просмотров 46K

Много начинающих верстальщиков и веб-разработчиков сталкиваются с ситуацией, когда элементы на странице ведут себя не так, как ожидается, и данное поведение кажется абсурдным. Но не стоит забывать, что существующие доминирующие технологии созданные людьми думающими, а если эта технология ещё и проверенная временем, значит, в таком странном, на первый взгляд, поведении, была и остается необходимость.

Наверное, каждый сталкивался со свойством border-collapse для таблиц. Известно, что данное свойство со значением border-collapse:collapse удаляет одну из границ для соседних ячеек таблицы, предотвращая дублирование их границ. Схоже работает и особенность блочной модели, называемая схлопыванием внешних отступов (англ. — Collapsing Margin). Схлопывание внешних отступов — особенность блочной модели CSS, которая заключается в наложении вертикальных внешних отступов двух или более блочных элементов (которые могут быть или не быть соседями) для формирования одиночного внешнего отступа. Отступ, сформировавшийся в результате данного объединения, называется схлопнувшимся отступом. Заметьте, что данная особенность применима только к вертикальным отступам элемента, т.е. к margin-top и margin-bottom.

Для упрощения, представляйте схлопывание следующим образом: когда внешние вертикальные отступы блочных элементов соприкасаются, то остается отступ, значение которого равняется значению большего из них, при этом значение отступа элемента с меньшей границей равно нулю. На рисунке ниже размер одной клетки фонового рисунка равен 20 пикселей; как видим, отступ между элементами равен 40 пикселей, хотя на первый взгляд, глядя на код, человеку, не знакомому с принципами схлопывания, может показаться, что блоки размещены неправильно, так как их отступы не плюсуются:

#block1 {
   margin:40px;  /*Задаем для первого блока отступы со всех сторон 40 пикселей */
}

#block2 {
    margin:40px; /*Задаем для второго блока отступы аналогично первому */
    margin-top:20px; /* Переопределяем верхний отступ */
}

*Исходный код примера

В случае, если одна с величин имеет минусовое значение, то финальное значение схлопнувшегося отступа формируется путем суммирования исходных значений блочных элементов. В случае, если обе величины отрицательные, то используется большее отрицательное значение (меньшее с арифметической точки зрения). Например, если бы block1 имел значение margin-bottom:-60px, а блок block2 margin-top:50px, то финальное значение отступа между элементами было бы минус 10 пикселей.

Как и в любой другой концепции, здесь тоже бывают исключения, поэтому схлопывание не работает в следующих случаях:

  • с «плавающими» блоками, которые используют свойство float;
  • с корневыми элементами(html, body);
  • с абсолютно позиционируемыми элементами, имеющих свойство и значение position:absolute;
  • в строчных элементах.

Существуют также специфические исключения, применяемые в зависимости от того, в каком иерархическом взаимодействии находятся блоки (об этом ниже):

  • Если элементы имеют значение свойства overflow, отличимое от visible, то в таких элементах не схлопываются отступы с отступами их наследников.
  • Элементы со свойством cleared не схлопываются верхними отступами с нижними отступами их родителей.

Теория может быть сложна для понимания, поэтому перейдем к примерам. Рассмотрим классические случаи, существующие в наследовании: когда блоки имеют связь потомок-потомок (sibling-sibling), элементы соседствуют друг с другом и имеют общего родителя; а также когда блоки имеют связь родитель-потомок (parent-child) — один элемент вложенный в другой. В обоих случаях схлопывание успешно применяется, но имеет несколько нюансов, о которых стоит поговорить.

Соседние элементы и схлопывание

Обычно, исключая применения дополнительных свойств, внешние отступы любых соседних не корневых блочных элементов схлопываются, пример схлопывания соседних элементов приведен выше.

Иногда требуется избежать данного эффекта. Кроме применения свойств, перекрывающих схлопывание, можно использовать некоторые хитрости, например, не задавать элементам значения отступа, кроме единого отступа — сверху или снизу, но если таким образом задать значения ряду элементов, может возникнуть потребность в уточнении отступов для первого или последнего элемента относительно родительского, или же менять его поле:

#parent {
    margin: 40px;
    border:1px dashed white;
    background:rgba(150, 0, 255, 0.2);
    width:204px;
}  /* Для визуальной симметрии потребовалось бы добавить padding-bottom:20px; */

.block {
    height:16px;
    margin-top: 20px;
    border:2px solid white;
    background:rgba(150, 0, 255, 0.7);
}

*Исходный код примера

Как видим, здесь нужно добавлять родительскому элементу нижнее внутреннее поле для того, что бы выровнять все элементы. Стоит ли ломать ноги, что бы подставлять костыли — дело вкуса, но я бы не советовал.

Схлопывание отступов элементов, связанных родительской связью

В данном случае схлопывание работает немного запутаннее и сложнее, чем в примерах выше. Для начала нужно знать, что отсупы блоков схлопываются соответствующими полями. Это значит, что верхнее поле родителя схлопнется с верхним полем своего потомка. Для рассмотрения данной ситуации представим, что имеется три блока: внешний блок-родитель, блок-родитель и дочерний блок. Для того, чтобы сработало схлопывание, нужно что бы блок-родитель не имел ни полей, ни границ (их значения были нулевые). Таким образом, внешние поля этих элементов соприкасаются. Заметьте, что нулевые значения внутренних полей и границ для родителей — обязательное условие срабатывания схлопывания.

.outside_parent {
    margin-top:40px;
    margin-left: 40px;
    border:2px dotted black;
    background:rgba(150, 0, 255, 0.7);
}

.parent {
    padding:0px; /* Обратите внимание что внутренние отступы равны 0 */
    border:0px solid grey; /* Полей у родителя так же не должно быть */
    margin-top: 40px; /* Этот отступ схлопнулся с дочерним */
    background:rgba(150, 0, 255, 0.7); 
}

.daughter {
    width: 196px;
    margin-top:60px; /* Актуальное значения отступа */
    border:2px solid white;
}

*Исходный код примера

Напомню, что размер одной клетки равно 20 пикселей, поэтому без схлопывания отступ между элементами был бы 60+40 пикселей, но из-за применения данного эффект он равен максимальному значению одного из элементов, в данному случае — 60 пикселям(3 клетки). Видим, что отступ дочернего блока заменяет верхний отступ для своего родителя. Если для родительского элемента задать что-либо: поле (padding) или же границу (border), то схлопывание не применится и расстояние между первым блоком и вторым будет очевидные 100 пикселей. Таким способом, можно управлять наличием данного эффекта, добавляя маленькое поле, либо же бесцветную границу, допустим, толщиной 1 пиксель, тем самым отключая эффект схлопывания.
На первый взгляд может показаться, что эфект работает только при формировании структуры как в примере выше, но это не так: схлопывание сработает и между соседними элементами, когда у них вложенные другие блоки. Рассмотрим ситуацию, когда имеется внешний блок и два блока, один с которых вложенный в другой.

.outside {
    height:16px;
    margin: 20px 0 0 40px;
    border:2px solid white;
    background:rgba(150, 0, 255, 0.7);
    margin-bottom:20px; /* Этот отступ так же схлопнулся */
}

.parent {
    margin-top:40px; /* Этот отступ схлопнулся с дочерним */
    margin-left:40px;
} /* Родительский блок не должен иметь ни полей ни границ для срабатывания эффекта */

.daughter {
    margin-top:60px; /* Актуальный схлопнувшийся отсуп */
    border:2px solid white;
}

*Исходный код примера

Примечательно, что схлопывание в примере выше сработало два раза: сначала схлопнулись отступы родительского и дочернего элемента, потом сформировавшийся отступ схлопнулся с нижним отступом внешнего элемента.

Вывод

Для хорошего специалиста важно контролировать все надлежащие ему инструменты и атрибуты: хорошего механика волнует не только количество клапанов в двигателе, но и наличие хорошей системы впрыска топлива и качество самого топлива. Так и хороший веб-разработчик должен контролировать каждый пиксель и не терять важные детали в структуре сайта.

Дьявол в мелочах, дьявол в пикселях.

Is there a way to disable margin-collapsing altogether? The only solutions I’ve found (by the name of «uncollapsing») entail using a 1px border or 1px padding. I find this unacceptable: the extraneous pixel complicates calculations for no good reason. Is there a more reasonable way to disable this margin-collapsing?

Shawn's user avatar

Shawn

45.7k3 gold badges21 silver badges54 bronze badges

asked Oct 31, 2013 at 23:53

kjo's user avatar

4

There are two main types of margin collapse:

  • Collapsing margins between adjacent elements
  • Collapsing margins between parent and child elements

Using a padding or border will prevent collapse only in the latter case. Also, any value of overflow different from its default (visible) applied to the parent will prevent collapse. Thus, both overflow: auto and overflow: hidden will have the same effect. Perhaps the only difference when using hidden is the unintended consequence of hiding content if the parent has a fixed height.

Other properties that, once applied to the parent, can help fix this behaviour are:

  • float: left / right
  • position: absolute
  • display: flex / grid

You can test all of them here: http://jsfiddle.net/XB9wX/1/.

I should add that, as usual, Internet Explorer is the exception. More specifically, in IE 7 margins do not collapse when some kind of layout is specified for the parent element, such as width.

Sources: Sitepoint’s article Collapsing Margins

8

One neat trick to disable margin collapsing that has no visual impact, as far as I know, is setting the padding of the parent to 0.05px:

.parentClass {
    padding: 0.05px;
}

The padding is no longer 0 so collapsing won’t occur anymore but at the same time the padding is small enough that visually it will round down to 0.

If some other padding is desired, then apply padding only to the «direction» in which margin collapsing is not desired, for example padding-top: 0.05px;.

Working example:

.noCollapse {
  padding: 0.05px;
}

.parent {
  background-color: red;
  width: 150px;
}

.children {
  margin-top: 50px;

  background-color: lime;      
  width: 100px;
  height: 100px;
}
<h3>Border collapsing</h3>
<div class="parent">
  <div class="children">
  </div>
</div>

<h3>No border collapsing</h3>
<div class="parent noCollapse">
  <div class="children">
  </div>
</div>

Edit: changed the value from 0.1 to 0.05. As Chris Morgan mentioned in a comment bellow, and from this small test, it seems that indeed Firefox takes the 0.1px padding into consideration. Though, 0.05px seemes to do the trick.

answered Oct 14, 2015 at 18:11

Nicu Surdu's user avatar

Nicu SurduNicu Surdu

8,0959 gold badges68 silver badges107 bronze badges

9

You can also use the good old micro clearfix for this.

#container::before, #container::after{
    content: ' ';
    display: table;
}

See updated fiddle: http://jsfiddle.net/XB9wX/97/

tjbp's user avatar

tjbp

3,4083 gold badges23 silver badges35 bronze badges

answered Aug 5, 2014 at 11:04

Blackgrid's user avatar

BlackgridBlackgrid

7905 silver badges6 bronze badges

7

Actually, there is one that works flawlessly:

display: flex;
flex-direction: column;

as long as you can live with supporting only IE10 and up

.container {
  display: flex;
  flex-direction: column;
    background: #ddd;
    width: 15em;
}

.square {
    margin: 15px;
    height: 3em;
    background: yellow;
}
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>

answered Nov 17, 2017 at 13:01

Daniel Koster's user avatar

1

overflow:hidden prevents collapsing margins but it’s not free of side effects — namely it… hides overflow.

Apart form this and what you’ve mentioned you just have to learn live with it and learn for this day when they are actually useful (comes every 3 to 5 years).

answered Nov 1, 2013 at 0:20

Litek's user avatar

LitekLitek

4,8881 gold badge24 silver badges28 bronze badges

3

I know that this is a very old post but just wanted to say that using flexbox on a parent element would disable margin collapsing for its child elements.

answered May 27, 2016 at 11:01

Hesam's user avatar

HesamHesam

1461 silver badge6 bronze badges

1

CSS* Fixes
display: flow-root;
✅ Parent element collapse
❌ Sibling element collapse
display: flex;
flex-direction: column;
✅ Parent element collapse
✅ Sibling element collapse

*Modern browsers (excluding IE11) support display: flow-root and display: flex.

Examples

section {
  background: green;
  outline: 2px solid purple;
}

p {
  background: yellow;
  margin: 1em 0;
}

section.flow-root {
  display: flow-root;
}

section.flex {
  display: flex;
  flex-direction: column;
}
<h2>Default</h2>  
<section>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</section>

<h2><code>flow-root</code> (Fixes only container)</h2>
<section class="flow-root">
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</section>

<h2><code>flex</code> (Fixes both container & siblings)</h2>
<section class="flex">
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</section>

anthumchris's user avatar

anthumchris

8,0452 gold badges28 silver badges53 bronze badges

answered Mar 9, 2020 at 21:14

Chuanqi Sun's user avatar

Chuanqi SunChuanqi Sun

1,11314 silver badges26 bronze badges

1

Every webkit based browser should support the properties -webkit-margin-collapse. There are also subproperties to only set it for the top or bottom margin. You can give it the values collapse (default), discard (sets margin to 0 if there is a neighboring margin), and separate (prevents margin collapse).

I’ve tested that this works on 2014 versions of Chrome and Safari. Unfortunately, I don’t think this would be supported in IE because it’s not based on webkit.

Read Apple’s Safari CSS Reference for a full explanation.

If you check Mozilla’s CSS webkit extensions page, they list these properties as proprietary and recommend not to use them. This is because they’re likely not going to go into standard CSS anytime soon and only webkit based browsers will support them.

Neil's user avatar

Neil

8,8558 gold badges43 silver badges49 bronze badges

answered Dec 3, 2014 at 23:39

Dan Carter's user avatar

Dan CarterDan Carter

5775 silver badges8 bronze badges

2

To prevent margin collapsing between siblings, add display: inline-block; to one of the siblings (one is enough though you can add it to both).

answered Mar 29, 2021 at 10:01

GorvGoyl's user avatar

GorvGoylGorvGoyl

40.7k27 gold badges222 silver badges218 bronze badges

Try

{
 display:flex;
 flex-direction:column;
}

or

{
   display:grid;
}

Mohit Kushwaha's user avatar

answered Dec 26, 2021 at 5:08

Dharmik Gohil's user avatar

I had similar problem with margin collapse because of parent having position set to relative. Here are list of commands you can use to disable margin collapsing.

HERE IS PLAYGROUND TO TEST

Just try to assign any parent-fix* class to div.container element, or any class children-fix* to div.margin. Pick the one that fits your needs best.

When

  • margin collapsing is disabled, div.absolute with red background will be positioned at the very top of the page.
  • margin is collapsing div.absolute will be positioned at the same Y coordinate as div.margin
html, body { margin: 0; padding: 0; }

.container {
  width: 100%;
  position: relative;
}

.absolute {
  position: absolute;
  top: 0;
  left: 50px;
  right: 50px;
  height: 100px;
  border: 5px solid #F00;
  background-color: rgba(255, 0, 0, 0.5);
}

.margin {
  width: 100%;
  height: 20px;
  background-color: #444;
  margin-top: 50px;
  color: #FFF;
}

/* Here are some examples on how to disable margin 
   collapsing from within parent (.container) */
.parent-fix1 { padding-top: 1px; }
.parent-fix2 { border: 1px solid rgba(0,0,0, 0);}
.parent-fix3 { overflow: auto;}
.parent-fix4 { float: left;}
.parent-fix5 { display: inline-block; }
.parent-fix6 { position: absolute; }
.parent-fix7 { display: flex; }
.parent-fix8 { -webkit-margin-collapse: separate; }
.parent-fix9:before {  content: ' '; display: table; }

/* Here are some examples on how to disable margin 
   collapsing from within children (.margin) */
.children-fix1 { float: left; }
.children-fix2 { display: inline-block; }
<div class="container parent-fix1">
  <div class="margin children-fix">margin</div>
  <div class="absolute"></div>
</div>

Here is jsFiddle with example you can edit

answered Jun 1, 2016 at 7:47

Buksy's user avatar

BuksyBuksy

11.4k8 gold badges62 silver badges68 bronze badges

For your information you could use
grid but with side effects :)

.parent {
  display: grid
}

answered Aug 16, 2017 at 7:30

Whisher's user avatar

WhisherWhisher

30.9k31 gold badges119 silver badges200 bronze badges

0

Горизонтальные внешние отступы имеют весьма не хорошее свойство схлопывания, что не на шутку мешает работе верстальщика. В этой статье описаны способы, которые позволят обойти эту проблему.

схлопывание margin

Схлопывание — процесс наложения внешних отступов в вертикальном направлении между смежными объектами или между родителем и его дочерним элементом. Схлопывание может происходить только по вертикали, горизонтального не существует.

При создании интернет-ресурса важнейшим аспектом является размещение структурных составляющих на странице. Не редко одним из инструментов корректировки положения элементов является свойство margin.

При использовании этого свойства стоит обращать внимание на характерную его особенность — верхние и нижние отступы имеют возможность схлопывания. Это усложняет процесс размещения структурных элементов на странице.

В зависимости от вида схлопывания мы предлагаем несколько решений этой проблемы.

Хотите насладиться настоящей японской кухней? Закажите японскую еду с доставкой в Ям Ям Новороссийск прямо сейчас!. пожарная сигнализация монтаж установка.

Схлопывание между смежными объектами

Простейшим способом исправления схлопывания является его отсутствие. То есть необходимо позиционировать элементы так, чтобы соседние их стороны имели только один отступ. К примеру, использовать только верхние отступы для объектов или только нижние.

Однако в таком случае возникает одно неудобство — отсутствие гибкости в расположении элементов. К примеру, первый или последний элемент должен иметь особы отступ, не такой как у всех элементов. В таком случае нужно будет прибегнуть к псевдоклассам :first-child или :last-child.

Схлопывание между родителем и потомком

В такой ситуации существует два возможных варианта удаления проблемы. Первый заключается в установке внутреннего отступа для нужной стороны родителя. Тот же эффект окажет наличие границы (border), которую можно сделать или прозрачной, или таким же цветом, как и сам контейнер. В результате чего ее не будет видно.

К особенностям этого способа нужно отнести то, что четко фиксированная высота изменится из-за наличия внутренних отступов. Точнее браузер будет прибавлять величину отступа к указанной высоте и реальная ее величина изменится.

Еще одним неплохим решением в данных условиях будет обращения к свойству overflow. Схлопывание будет устранено, если значение свойства будет не visible, а какое-нибудь другое. Также необходимым условием для работы метода является наличие фиксированного размера ширины или высоты объекта.

Стоит обратить внимание на наличие негативных последствий этого метода. При использовании свойства overflow контент может прокручиваться или вообще обрезаться, в зависимости от указанных значений ширины и высоты.

Удаление схлопывания для смежных элементов и между родителем и потомком одновременно

Рассмотренные сейчас варианты могут оказаться универсальными решениями, однако не всегда их удобно применять.

Первое решение основывается на замене внешних отступов границами. Для этого определяем цвет границы идентичным фону блока. Однако стоит отметить, что применения такого способа не желательно по ряду причин:

  1. Использование свойства не по назначению
  2. Не сработает, если для объекта уже были указаны границы
  3. Также не сработает при наличии полицветного фона.
  4. Для IE6 толщина границы будет входит в перерасчет высоты блока, что необходимо учитывать.

Допускается также заменять позиционирование внешними отступами на расположение через внутренние — свойство padding. В этом случае нужно помнить о двух важных моментах. Первый заключается в том, что на внутренние отступы распространяется заливка заднего фона объекта. А также значение padding влияет на перерасчет высоты блока.

Расположить элементы посредством абсолютного позиционирования. В этом случае за объектом не будет закреплено место в структуре страницы. Это не всегда желательный эффект.

Схлопывание не происходит, когда блок обладает свойствами плавающего объекта. Проблема этой методики идентична с абсолютным позиционированием — выпадение из общей структуры.

В каких браузерах работает?

6.0+ 7.0+ 9.5+ 4.0+ 3.0+

Курсы по CSS (в открытом доступе)

Уровень сложности:

Средний

Дата публикации: 23.11.2010

В некоторых случаях вертикальные внешние отступы (margin-top и margin-bottom) смежных элементов или родителя и первого/последнего потомка могут схлопываться. Подробнее об этом читай в статье Схлопывание margin.

Иногда схлопывание отступов мешает. Давай посмотрим, как от него можно избавится.

Задача

«Отучить» margin схлопываться.

Решения

Вариантов решения много. У каждого есть своя область применения, свои особенности и, к сожалению, свои недостатки.

Убираем схлопывание между смежными элементами

Самый простой способ, не обходить схлопывание, а сделать так, чтобы его не могло быть в принципе, т.е. исключить ситуацию, когда рядом идут два отступа. Например, для смежных элементов задаем только margin-bottom или только margin-top.

Недостаток

  • Такой подход очень негибкий. Для первого или последнего элемента отступ придется определять дополнительно, возможно с использованием псевдокласcов :first-child или :last-child, которые поддерживаются не всеми браузерами (:first-child не понимает IE6, а :last-child не понимает ни IE6, ни IE7).

Смотрим Демо-пример.

  • IE 6-8
  • Firefox 3.0
  • Opera 9.5-10.5
  • Safari 4
  • Chrome 7

Убираем схлопывание между родителем и дочерними элементами

  1. Для родительского элемента с нужной стороны задаем однопиксельный padding или однопиксельный прозрачный border (для IE6 задаем границу фоновым цветом элемента). Учти, что высота элемента при этом увеличивается на 1px!

    Недостатки

    • Если высота у элемента жестко задана, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
    • IE6 не поддерживает прозрачный цвет границ, для него нужно задавать границу фоновым цветом элемента — имеем лишнее правило.
  2. Для родителя задаем overflow со значением отличным от visible.

    Недостатки

    • Чтобы overflow заработало, у элемента должен быть четко прописан хотя бы один из размеров;
    • Нежелательный эффект от применения overflow (контент либо обрезается либо прокручивается, а это может не соответствовать задумке дизайнера).

Смотрим Демо-пример.

  • IE 6-8
  • Firefox 3.0
  • Opera 9.5-10.5
  • Safari 4
  • Chrome 7

Убираем схлопывание как между смежными элементами, так и между родителем и дочерними элементами

  1. Вместо одного или обоих вертикальных margin ставим границы (border) аналогичного размера. Цвет границ должен совпадать с цветом фона родителя для создания эффекта прозрачного пространства.

    Недостатки

    • Не очень красивое решение: границы должны использоваться в качестве границ, а не в качестве отступов.
    • Если у элементов уже заданы границы, то этот способ неприменим.
    • Способ неприменим, если элемент расположен на неоднородном фоне.
    • Если у элемента кроме внутреннего отступа жестко задана еще и высота, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
  2. Вместо одного или обоих вертикальных margin ставим внутренние отступы элемента padding.

    Недостатки

    • Можно применять не всегда. Внутренний отступ залит фоновым цветом элемента, а внешний отступ — нет. Если по дизайну элемент имеет свою раскраску, этот метод неприменим.
    • Если у элемента кроме внутреннего отступа жестко задана еще и высота, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
  3. Позиционируем элемент абсолютно (position:absolute;).

    Недостаток

    • Абсолютно спозиционированный элемент выпадает из потока, а это, в большинстве случаев, нежелательно.
  4. Делаем элемент плавающим (float).

    Недостаток

    • Как и в предыдущем случае, плавающий элемент выпадет из потока, что может доставить лишние хлопоты с позиционированием последующих элементов.
  5. Update 24.10.2010 by SelenIT. Задаем для элемента, участвующего в схлопывании, свойство display:inline-block/table/inline-table/table-cell.

Смотрим Демо-пример.

  • IE 6-8
  • Firefox 3.0
  • Opera 9.5-10.5
  • Safari 4
  • Chrome 7

Выводы

Схлопывание margin между смежными элементами, как правило, позволяет более удобно реализовать отступы в контентной части. А вот ситуация, когда схлопываются вертикальные отступы дочернего и родительского элемента, чаще всего нежелательна. Существует ряд способов обойти схлопывание. Стоит ли это делать, и какой способ выбрать — решаем для каждого конкретного случая отдельно.

Материалы:

  • W3C:: Box model :: Collapsing margins
  • UEric A. Meyer :: Uncollapsing Margins

Понравилась статья? Поделить с друзьями:
  • Как составить договор купли продажи основных средств
  • Как найти частоту вращения шлифовального круга
  • Как исправить ошибку в гугл аккаунт
  • Как риелтору найти клиентов
  • Как найти папку shell