Collapsing Margins / Borders in CSS

Here's a simple example of the kind of unexpected behavior caused by collapsing margins in CSS.

<div style="background-color: red">
<h2 style="background-color: cyan">
Hello flawed world!
</h2>
</div>


The Problem


When displayed, (tested in Firefox 3.5.7) the code above produces the text "Hello flawed world!" on a cyan background, and nothing else. This is not as expected.

The <h#> tags have a built-in top and bottom margin to them of around 20px. Now, a margin, specifically, is white-space surrounding a tag, outside of it. Margins push out from a block's position to create empty space around it. With this in mind, the code above should produce 20px worth of red - the background color of the <div> containing the <h2> - above and below our cyan-backed text. But it doesn't.

Meet the concept of collapsing margins. Because nothing whatsoever has been placed in the space between the div's borders and the h2's borders, the browser is taking it upon itself to remove what it perceives as empty-space by collapsing the margins together.

I don't know why it might be beneficial for the browser to collapse margin-space this way, nevertheless here we are. We must work around it.

The Solution


In order to get the desired margins to appear we must prevent the browser from perceiving them as empty. The simplest, most unobtrusive thing to shove in the gap is a bit of padding. Padding is sort of the inverse of margins, in that it creates white space within the block, rather than outside it; pushing inward from the borders. 1px worth of padding will keep your margins and borders from falling in on themselves.

<div style="background-color: red; padding: 1px 0;">
<h2 style="background-color: cyan">
Hello flawed world!
</h2>
</div>


The corrected code inserts 1px worth of top and bottom padding to the div. Again, note that the padding is added to the outer container. It pushes inward, giving the previously empty space between the edge of the h2 block and the edge of the div block a tiny bit of content. In the example I've used the 2-value format of the 'padding' style, where the first value represents top and bottom padding, and the second left and right.

I've always looked at margins and padding as being the same thing in a different direction. Apparently this isn't entirely true. For some reason the CSS standard views white-space created by margins as sacrificial when unoccupied, but maintains a hallowed view of white-space declared as padding. Preserving padding makes sense. Not preserving margins... I'm sure there's a reason, but from the coders perspective it seems an inconsistency.

0 comments:

Post a Comment