Обходим схлопывание margin
В некоторых случаях вертикальные внешние отступы (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
Убираем схлопывание между родителем и дочерними элементами
-
Для родительского элемента с нужной стороны задаем однопиксельный padding или однопиксельный прозрачный border (для IE6 задаем границу фоновым цветом элемента). Учти, что высота элемента при этом увеличивается на 1px!
Недостатки
- Если высота у элемента жестко задана, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
- IE6 не поддерживает прозрачный цвет границ, для него нужно задавать границу фоновым цветом элемента — имеем лишнее правило.
-
Для родителя задаем overflow со значением отличным от visible.
Недостатки
- Чтобы overflow заработало, у элемента должен быть четко прописан хотя бы один из размеров;
- Нежелательный эффект от применения overflow (контент либо обрезается либо прокручивается, а это может не соответствовать задумке дизайнера).
Смотрим Демо-пример.
- IE 6-8
- Firefox 3.0
- Opera 9.5-10.5
- Safari 4
- Chrome 7
Убираем схлопывание как между смежными элементами, так и между родителем и дочерними элементами
-
Вместо одного или обоих вертикальных margin ставим границы (border) аналогичного размера. Цвет границ должен совпадать с цветом фона родителя для создания эффекта прозрачного пространства.
Недостатки
- Не очень красивое решение: границы должны использоваться в качестве границ, а не в качестве отступов.
- Если у элементов уже заданы границы, то этот способ неприменим.
- Способ неприменим, если элемент расположен на неоднородном фоне.
- Если у элемента кроме внутреннего отступа жестко задана еще и высота, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
-
Вместо одного или обоих вертикальных margin ставим внутренние отступы элемента padding.
Недостатки
- Можно применять не всегда. Внутренний отступ залит фоновым цветом элемента, а внешний отступ — нет. Если по дизайну элемент имеет свою раскраску, этот метод неприменим.
- Если у элемента кроме внутреннего отступа жестко задана еще и высота, нужно исправлять значение высоты для IE6 в режиме обратной совместимости.
-
Позиционируем элемент абсолютно (position:absolute;).
Недостаток
- Абсолютно спозиционированный элемент выпадает из потока, а это, в большинстве случаев, нежелательно.
-
Делаем элемент плавающим (float).
Недостаток
- Как и в предыдущем случае, плавающий элемент выпадет из потока, что может доставить лишние хлопоты с позиционированием последующих элементов.
- Update 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
- Eric A. Meyer :: Uncollapsing Margins