Обходим схлопывание margin

Дата публикации: 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!

    Недостатки

  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 между смежными элементами, как правило, позволяет более удобно реализовать отступы в контентной части. А вот ситуация, когда схлопываются вертикальные отступы дочернего и родительского элемента, чаще всего нежелательна. Существует ряд способов обойти схлопывание. Стоит ли это делать, и какой способ выбрать — решаем для каждого конкретного случая отдельно.

Материалы: