Margin collapse and how to get rid of it?

margin collapse
and how to get rid of it?

margins in valid browsers act different than all the IE’s, while borders and paddings word differently in old IE (broken box model)
is there nothing that works identically in all browsers!!! (without tricks i mean)

i know of couple tricks to remove margin collapse, one is to add a padding-top:1px to the container,
but this messes up old IE if the height is set…
what are the other tricks?

in my opinion margin-collapse should be limited only on <p>, <h1>, <h2> etc
or at least never to occur on <div> to give designers a alternative to work with.

too bad there is no css to just disable margin collapse…

article on topic.

just found another method, adding

display:inline-block;

to the child with the margin removes it from affecting margin-collapse
(make sure to give it a width because of the shrink-wrap, like width:100%)

All you’re doing is triggering hasLayout. A safe method (inline-block has side effects) is to add {zoom: 1;}, which will set hasLayout without other consequences.

cheers,

gary

i believe you are wrong.
there is no hasLayout in firefox.

i am aware that display:inline-block; triggers hasLayout in IE, but ie does not have margin collapse anyway.

additionally, adding

display:inline-block
followed by
display:block

is equally safe to trigger has layout in IE

example:


display:inline-block;
display:block;

haslayout will remain even though im overwriting the display rule.

but this is not what im asking, im asking for methods to remove margin collapse in modern browsers.

YuriKolovsky, a much simpler way of fixing margin collapsing is to add a border to the top of the element (1px sold transparent would probably work, if not the color of the background), I find that works every time (and if the 1px is a problem, just add a 1px negative top margin!) :slight_smile:

just add a 1px negative top margin!

riiight, whats how i did it before, dang, too much time spent on complicated schemes i guess. xD
display:inline-block also works by the way.

it still causes a 1px difference in IE5 if you have the height set on the maincontainer.

edit:

also giving it a transparent border that works cross browser is probably better


border:1px dashed transparent;/*cross browser transparent border*/

I’m sorry, I misunderstood your issue. Inline-block does trigger a new block formatting context, of which hasLayout is a buggy implementation, but I leapt to the erroneous idea you were concerned with older IEs. :shrug:

IE<8 does collapse margins, though not properly. Even whether the margin values are explicitly author-set, or implicit in the default values affects how it’s implemented.

Have a care about resetting the property value. This does (and should) not work as expected.

selector  {
  display:inline-block;
  display:block;
  }

Only the last value of a property, i.e. the second display, is applied. To set hasLayout and then reset the display value, you must do it with separate selectors.

selector {
  display: inline-block;
  }

selector {
  display: block;
  }

You may have meant that, but your example will have been misleading.

cheers,

gary

thanks gary.turner, you are correct, my example was indeed misleading.

He mentioned he can’t do this in his fiirst post due to older IEs screwing up with a height set …:wink:

Collapsing margins are often misunderstood by even proficient CSS authors especially when browsers handle things differently even if we exclude bugs.

Margins on certain elements however should not collapse.

From the specs you can see a whole rage of exclusions (including inline-box);

i.e.

Vertical margins may collapse between certain boxes:

  • Two or more adjoining vertical margins of block boxes in the [URL=“http://www.w3.org/TR/CSS21/visuren.html#normal-flow”]normal flow collapse. The resulting margin width is the maximum of the adjoining margin widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the absolute maximum of the negative adjoining margins is deducted from zero. Note. Adjoining boxes may be generated by elements that are not related as siblings or ancestors.
  • Vertical margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
  • Vertical margins of elements that establish new block formatting contexts (such as floats and elements with ‘overflow’ other than ‘visible’) do not collapse with their in-flow children.
  • Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
  • Margins of inline-block elements do not collapse (not even with their in-flow children).
  • If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it. In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.
    [LIST]
  • If the element’s margins are collapsed with its parent’s top margin, the top border edge of the box is defined to be the same as the parent’s.
  • Otherwise, either the element’s parent is not taking part in the margin collapsing, or only the parent’s bottom margin is involved. The position of the element’s top border edge is the same as it would have been if the element had a non-zero bottom border.
    [/LIST]

IE6/7 will behave differently if in “haslayout” mode and mimics the behaviour that other browsers apply when overflow other than visible is applied. (Of course there are quite a few other bugs in IE as well to be careful of.)

i cant get

Vertical margins of elements that establish new block formatting contexts (such as floats and elements with ‘overflow’ other than ‘visible’) do not collapse with their in-flow children.

to work…

the haslayout comment is interesting, i did not know that IE mimics margin collapse (or did i read the last part wrong?).

That’s saying if a parent has haslayout-the inner flow children won’t collapse.

And you misread-IE will mimic the above statement when in haslayout mode-like overflow:hidden on a parent will make the above statement true-IE in general just needs haslayout set.

all that you say ryan is gibberish to me?
im sorry but could you dumb down the language for me?

OOOOOOOokkkkkkkkkkkk

So say you have a structure like this
<element with overflow:hidden>
<element with float></element with float>
</element with overflow:hidden>

No collapsing margins there since the parent has overlfow:Hidden; and the inflow float won’t collapse

Also
IE doesn’t collapse margins wehn the parent has haslayout. Like overflow:hidden;. Look at the bold statement. IE will do the EXACT same thing as the bold statement when the parent has haslayout set-a width/height. Anything that sets it.

I can’t make it dumber :).

none of the articles about margin-collapse (that i managed to google for) mention this…
oh well, back to testing.

Mention what?

Hi,

Some previous articles of mine may be of interest as they mention a number of these issues and bugs.

The overflow/haslayout effects are mentioned in the Sitepoint Reference that i linked to earlier.

Of course there are still many bugs as I mentioned before but it’s good to know how things should work.:slight_smile:

There is also another point worth mention here and that is IE’s behavior when “haslayout” has been applied to the element. When the outer div has “haslayout” applied (e.g if it has a width) then it stops collapsing the margins and we get the result shown in Pic. 4 without the need for padding or borders to stop the collapse. However, IE is the only browser that will do this and it is probably the reason that collapsing margins aren’t well understood because in most cases these elements may already have “haslayout” and the margins do not collapse.
here

ok, one misunderstanding gone, i was sure that IE did not have any margin-collapsing and was confused at first to hear that it did.