May 7th, 2007 - by Paul OB

Collapsing Margins

When you work with CSS it won’t be long before you run into margin issues and while we have covered the general issues in a previous article I would like now to talk a bit about collapsing margins. If you are not familiar with how vertical adjacent margins (including nested elements) are handled then I will quickly explain the basics and all will become clear.

The W3C specification defines them as follows:

8.3.1 Collapsing margins

“In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding or border areas or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.”

What this means in simple terms is that if you have two divs following each other in the normal flow and each div has a 20px margin all around, then the vertical gap between the two divs will still only be 20px due to collapsing margins. It will not be 40px as might be expected.

If the divs had different margins then only the greater margin would apply. (e.g. If one div has a 30px margin and one div has a 15px margin then the margin would be 30px because it is the greatest margin. You do not add them together and halve them or anything like that. It’s just the greater margin that will apply.)

Horizontal margins do not collapse in CSS 2.1 but vertical margins will collapse between certain elements and this can be easily demonstrated with a simple example.

  1. *{margin:0;padding:0}
  2. #outer{ background:red;}
  3. #outer2{ background:yellow;}
  4. div {margin:20px}
  1. <div id="outer">test</div>
  2. <div id="outer2">test</div>

In the above code both elements have a 20px margin and although the top element has a 20px bottom margin and the bottom element has a 20px top margin, the resulting margin is not 40px but collapses to the bigger of the 2 margins which in this case is 20px. (Note that I have zeroed all margins and padding so that the results are not skewed by any stray margins or padding that are lurking around.)

Here is a screenshot resulting from the above code:

Pic. 1:

div-margin.gif

This also applies to nested elements – if one element is nested inside another then the top margin will collapse into one single margin. Again, this is best demonstrated with a small piece of code seen here:

  1. *{margin:0;padding:0}
  2. #outer{
  3. background:red;
  4. margin:20px;
  5. }
  6. p {margin:20px;background:yellow}
  1. <div id="outer"><p>test</p></div>

From this code you may expect that the outer element will be 20px from the top and the inner element will be 20px inside the element. Here is a picture of what you may have expected to happen.

Pic. 2:
withlayout.gif

The above sounds logical but is not the result you will get due to the margins collapsing – the actual result can be seen in the following image:

Pic. 3:

nested.gif

I have purposely left a left margin of 20px on the inner p element so that you can see the red background of the div which clearly indicates that they are both occupying the same space. The 20px margin on the inner p element has collapsed to zero and the only margin in effect is the 20px margin on the outer div. This behavior of collapsing margins is a little unintuitive because usually the result in Picture 2 is normally what is required.

In order to replicate the result as shown in Pic. 2 above we would need to add some padding or a border in the way so that there is something solid between the margins and then they will not collapse. We can do this quite simply as follows:

  1. #outer{
  2. background:red;
  3. margin:20px;
  4. padding:1px;
  5. }
  6. p {margin:19px;background:yellow}

The result is exactly the same as in Pic. 2 above but I reproduce it here again anyway in Pic. 4.

Pic. 4:

withlayout.gif

I used a 19px margin on the p element because I have added a 1px top padding and 19+ 1 = 20px which was the original gap I required. While this method can be a little bit of a nuisance at times it does show that the margins can be controlled quite easily and allows the best of both worlds where outer margins can collapse and nested inner elements can have their margins applied.

Margins on Inner Element Only

Now that you understand the basics of collapsing margins, study the following code and see if you can work out what the result will be without looking at the answers below.

  1. *{margin:0;padding:0}
  2. #outer{
  3. background:red;
  4. margin:0;
  5. }
  6. p{
  7. background:yellow;
  8. margin:20px;
  9. }
  1. <body>
  2. <div id="outer">
  3. <p>Inner content</p>
  4. </div>

As #outer doesn’t have any margins then you are probably expecting that no collapse will take place and that the result will be as shown in Pic. 5 below.

Pic. 5:

innermargin.gif

Although this sounds perfectly reasonable it is not going to be the result you will get. The 20px top margin on the p tag collapses and effectively becomes the 20px top margin on #outer instead and that means #outer is pushed 20px down from the top of the viewport. You could view it as though the margin of the p tag extends through #outer because there is nothing in the way to stop it and thus all elements are moved downwards.

e.g.

Pic. 6:
nested2.gif

In order to get the result as shown in Pic. 5 you would need to add padding or borders as previously shown to stop the collapse from taking place.

Bugs:

There is also another point worth mention here and that is IE’s behavior when “haslayout” has been applied to the element. (If you don’t know what haslayout is then read the FAQ in the SitePoint forums first and then come back here.) 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. Therefore you need to use the padding/border method for a full proof solution to this.

HTML and Body

Other behaviors to be wary of are when you apply a margin to the HTML element. According to the specs the margins when applied to the root element (HTML) should not collapse. This means you can safely add a 25px margin to the HTML element and know that the margin will be applied. Even IE will obey this. On the other hand if you apply a 25px margin to the body element then the margin will collapse with other margins on the page.

IE, unfortunately (once again), gets this wrong and will not collapse the margin when applied to the body element and treats it as if it were applied to HTML.

Non-collapsing Elements

There are some other elements (apart from HTML) that don’t have the collapsing margin behavior to them and some of the main ones to remember are as follows.

  • The vertical margins between a floated box and any other box do not collapse.
  • Elements with overflow set to something other than visible do not collapse with the margins of their children.
  • Absolute elements and inline-block elements do not have collapsing margins either.

You can read more special cases at the W3C specs if you enjoy reading those sorts of things but the main things to be wary of are already mentioned above.

I hope this has given you a small insight into how margins behave. The best way to understand them is to play around with the demos above and you will soon begin to get the hang of them.

Be Sociable, Share!

16 Responses to “Where’s My Margin Gone? (or why 1+1=1)”

1 Brendon Kozlowski

I don’t know how long I’ve been learning CSS, and in the, what I would guess, 2 years I have been working with it…I never knew about this. I feel that big imaginative light bulb above my head glowing vividly now. Thanks, Paul! This’ll definitely help tomorrow (and probably would have helped today). ;)

2 scriptygoddess » How margins work in CSS

[...] is a great article/tutorial on how margins work in css (why/when then collapse, and why/when they [...]

3 Golgotha

Hey Paul, what’s that tool you use in the screenshots to indicate the pixel widths?

4 Paul OB

Hi Mark, Its a little widget called calipers.

http://www.iconico.com/caliper/v3upgrade.aspx

I’ve used the free version for years and can’t live without it now :)

I may upgrade to the paid version as it has a lot more features.

5 Jelena

Wow, such a great article, Paul! I have to say that I had no idea about till now. :blush:

6 Golgotha

Hey Jelena, don’t feel bad, I don’t think I consciously knew about it either. I’m sure I’ve ran into it before… Probably banged my head against the wall for 20 minutes because of it before… and then ended up emailing Paul. That’s usually how I deal with these little CSS idiosyncrasies.

7 Paul OB

Thanks Jelena, Collapsing margins are a mis-understood section of CSS and one that can cause significant layout differences if you don’t account for them :)

8 Dean

This is the best explanation I’ve seen so far on this topic — thorough, and clearly written. Thanks, Paul.

I, unfortunately, have been aware of this problem. A few years ago I spent countless hours battling with collapsing nested margins and floats, eventually solving it by adding a 1px border.

But it was never really solved, because I didn’t completely understand why margins collapse in specific cases and not in others. With this article, hopefully, that will change and working with margins and floats will be easier now. Thanks again Paul. I appreciate your work.

9 itispals

I have always believed good articles entices visitors and today after going through these wonderful articles, i am subscribing to your website.
Keep up the good work.
regards,
itispals

10 johno

great article. I’ve had to explain this over and over again. I’ll now just point people to this post. Thanks.

11 The Positive Side of Negative Margins

[...] construct a number of paragraphs that all have a 20px top and bottom margin. You may recall from my collapsing margin article that adjacent margins of static elements will collapse into one margin. So each paragraph [...]

12 Chris

Two biggest complaints about CSS:

1. This retarded margin collapsing bs.
2. Not being able to easily center vertically.

With that out of the way, your writing style is nice and easy to follow.

13 Paul OB

Hi Chris,

Thanks for your comments and I have to agree that margin collapse works against us most of the times and would possibly be easier to handle if margins didn’t collapse at all.

Vertical centering is also a sore point and you have to jump through many hoops to achieve an effect that is easy with a table. There are methods but nothing straight forward.

Here’s an example:

http://www.pmob.co.uk/pob/vertical-center1.htm

I think someone was napping and they missed out how to vertically center elements when writing the specs. :)

14 Let’s Be Clear About This!

[...] it, then the parent container will be the margin’s starting point (you must also take into account collapsing margins of [...]

15 JohnM

I thought both the div and the p tag are block elements so that the margin of the nested p tag is not even touching the margin of the div in the first place because the p element is actually inside the div element. So why do you even need to add a pixel of border or padding when their not even touching in the first place?

16 Paul OB

Hi JohnM,

Collapsing margins apply to nested elements also and not just to adjacent elements. (vertical margins on inline elements do not apply anyway)

If you have a p element nested inside a div and there is no borders padding or content between the edges of the nested element then the vertical margin on the p element effectively collapses onto the outer element and becomes a margin on the div instead.

For example if the p element had a top margin of 1em it would not move the p element 1 em away from the parent div but would actually move the parent div 1em away from whatever was above it (assuming there were no more margin collapses above).

Try out the demos above to see this in action :)

Share your thoughts...

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading