Как отключить маржинальное свертывание?


203

Можно ли вообще отключить коллапс маржи? Единственные решения, которые я нашел (под названием «uncollapsing»), влекут за собой использование 1px border или 1px padding. Я считаю это неприемлемым: посторонний пиксель усложняет вычисления без веской причины. Есть ли более разумный способ отключить это сокращение полей?


4
Используйте макет Flex или Grid, где не существует
— Майкл Бенджамин,

Просто margin-bottommargin-top
— Дэн Брей

Я сделал пакет, чтобы сделать расчет проще: npmjs.com/package/collapsed-margin
— Оуэн М

Ответы:


255

Существует два основных типа обрушения маржи:

  • Свертывание полей между соседними элементами
  • Свертывание полей между родительскими и дочерними элементами

Использование отступов или бордюров предотвратит коллапс только в последнем случае. Кроме того, любое значение, overflowотличное от его default ( visible), примененного к родителю, предотвратит коллапс. Таким образом, оба overflow: autoи overflow: hiddenбудут иметь одинаковый эффект. Возможно, единственное отличие при использовании hidden- это непреднамеренное последствие скрытия контента, если родитель имеет фиксированную высоту.

Другие свойства, которые после применения к родителю могут помочь исправить это поведение:

  • float: left / right
  • position: absolute
  • display: inline-block / flex

Вы можете проверить их все здесь: http://jsfiddle.net/XB9wX/1/ .

Я должен добавить, что, как обычно, Internet Explorer является исключением. В частности, в IE 7 поля не сворачиваются, когда для родительского элемента указана какая-то компоновка, например width.

Источники: статья Sitepoint, Свертывание полей


1
обратите внимание, что заполнение также может повлиять на это, если оно не равно нулю
— Младен Янджетович

3
Обратите внимание, что это overflow: autoможет привести к появлению полос прокрутки в родительском элементе, а не к переполнению содержимого в соответствии с overflow: visible.
— Лев

«переполнение: авто» не работает в Chrome v44.
— tkane2000

3
Спасибо за показ: встроенный блок, это спасло меня :)
— alexcasalboni

3
Любое значение, flexотличное от значения по умолчанию, также отключит коллапс маржи
— Oly

60

Для этого вы также можете использовать старый добрый микрофиксон.

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

Смотрите обновленную скрипку: http://jsfiddle.net/XB9wX/97/


Превратили мой ответ в вики сообщества. Пожалуйста, не стесняйтесь расширять его своим ответом. Спасибо.
— hqcasanova

3
Я не понимаю, когда я смотрю на этот пример, поля рушатся (только 10px вертикальное пространство между div вместо 20px)
— Энди

1
Это помогает только в устранении коллапса между братьями и сестрами, к которым применен этот clearfix. Я разработал пример, чтобы продемонстрировать это: jsfiddle.net/dpyuyg07 - и даже это еще не все. Он только удаляет коллапс полей из дочерних элементов элементов, к которым вы применили это исправление. Если вы добавите поле для самого контейнера, поля все равно будут сжиматься
— NicBright

4
Я могу выразить это еще точнее: метод clearfix предотвращает только разрыв между родителями и детьми. Это не влияет на коллапс между соседними братьями и сестрами.
— NicBright

Я думаю , теперь я понимаю тенденцию Bootstrap, чтобы заполнить DOM с :beforeи :afterэлементами. Теперь я добавил это правило к моей таблице стилей: div:before, div:after{content: ' '; display: table;}. Фантастика. Внезапно вещи начинают вести себя как ожидалось.
— Стейн де Витт

60

Насколько мне известно, одним из хитрых приемов отключения сворачивания полей, который не оказывает визуального воздействия, является установка отступа родительского элемента в 0.05px:

.parentClass {
    padding: 0.05px;
}

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

Если требуется какое-то другое заполнение, тогда применяют заполнение только к «направлению», в котором, например, не требуется сворачивание полей padding-top: 0.05px;.

Рабочий пример:

.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>

Изменить: изменил значение с 0.1на 0.05. Как отметил Крис Морган в комментарии ниже, и из этого небольшого теста кажется, что действительно Firefox принимает во внимание 0.1pxотступы. Хотя, 0.05pxпохоже , делает свое дело.


2
Это мое любимое решение. Вы можете даже включить это как стиль по умолчанию. Почему нет? *{padding-top:0.1px}, Мы уверены, что он работает во всех браузерах?
— Ник Мэннинг

До сих пор работал довольно хорошо для меня, но я не претендую на то, что тщательно протестировал его в большинстве браузеров.
— Нику Сурду

2
Очень хорошее решение, похоже, работает как и ожидалось в большинстве браузеров. Спасибо, что поделились этим!
— wiredolphin

1
Это хитроумное решение , как это делает добавить дополнительные пиксели в различных условиях, из - за высокий DPI дисплеев и расчеты субпикселей. (Firefox
— Крис Морган,

0.05pxЯ бы предпочел, чтобы это был конкретный выбор, а не случайный номер обмана браузера 0.01px.
— Фолькер Э.

22

overflow:hidden предотвращает разрушение полей, но не лишено побочных эффектов, а именно ... скрывает переполнение.

Помимо этого и того, что вы упомянули, вы просто должны научиться жить с этим и учиться на этот день, когда они действительно полезны (приходит каждые 3-5 лет).


Превратили мой ответ в вики сообщества. Я думаю, что я рассмотрел побочный эффект, который вы упомянули в последних двух строках второго абзаца: возможно, единственное отличие при использовании скрытого - непреднамеренное последствие скрытия контента, если родительский объект имеет фиксированную высоту . Но если вы считаете, что это требует дальнейшего разъяснения, пожалуйста, не стесняйтесь вносить свой вклад. Спасибо.
— hqcasanova

7
overflow: autoхорошо использовать, чтобы предотвратить скрытое переполнение и все же предотвратить падение полей.
— Гэвин

@Gavin, overflow:auto;заставил мою область контента получить полосу прокрутки на некоторых страницах.
— Рид

13

На самом деле, есть один, который работает безупречно:

дисплей: гибкий; flex-direction: столбец;

до тех пор, пока вы можете жить с поддержкой только IE10 и выше

.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>


Для этого , чтобы работать в качестве универсального решения, необходимо добавить дополнительный <div>внутри .container, в противном случае .containerбудет контролировать бокс-модель своих детей. Например, встроенные элементы станут блочными элементами полной ширины; если у них есть маржа, они также будут обесценены.
— Зуп

9

Каждый браузер на основе webkit должен поддерживать свойства -webkit-margin-collapse. Есть также подвойства, чтобы установить его только для верхнего или нижнего поля. Вы можете присвоить ему значения свернуть (по умолчанию), отбросить (устанавливает для поля значение 0, если есть соседнее поле) и разделить (предотвращает сжатие поля).

Я проверял, что это работает на версиях Chrome и Safari 2014 года. К сожалению, я не думаю, что это будет поддерживаться в IE, потому что он не основан на webkit.

Прочитайте Apple Safari CSS Reference для полного объяснения.

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


Это хорошо, потому что это помогает нам устранить несоответствие в том, как Safari и Chrome справляются с наценками.
— Бьюдсон

8

Я знаю, что это очень старая статья, но я просто хотел сказать, что использование flexbox для родительского элемента отключило бы свертывание полей для его дочерних элементов.


Не только для своих дочерних элементов - он также предотвращает разрушение полей между родителем и первым и последним дочерним элементом.
— Свен Марнах

2

У меня была похожая проблема с коллапсом полей из-за того, что родитель positionустановил относительное значение. Вот список команд, которые вы можете использовать, чтобы отключить сжатие полей.

ЗДЕСЬ ИГРА ДЛЯ ТЕСТИРОВАНИЯ

Просто попробуйте присвоить любой parent-fix*класс к div.containerэлементу, или любой класс children-fix*к div.margin. Выберите тот, который соответствует вашим потребностям лучше всего.

когда

  • Маржа коллапса является отключена , div.absoluteс красным фоном будет расположен в самом верху страницы.
  • поле сжимается div.absolute будет располагаться в той же координате Y, что и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>

Вот jsFiddle с примером, который вы можете редактировать


1

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

ДЕМО (до)

.parent {
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

ДЕМО (после)

.parent {
  display: flow-root;
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>


0

Для вашей информации вы можете использовать сетку, но с побочными эффектами :)

.parent {
  display: grid
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.