DIV inside DIV, second DIV has a top-margin - why doesn't even that work?

I’m a self-proclaimed novice developer. But I’m having a serious case of the mondays. Check this out:

This is my HTML:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
  <title>Hello</title>
  </head>
  <body>


  <div id="a">
    <div id="b">Hello</div>
  </div>

  </body>
</html>

…and this is my CSS…

#a {
    background: #f00;
  }
  #b {
    background: #0f0;
    margin: 20px 0 0 0;
  }

Why won’t DIV #b push DIV #a up? I should see 20 pixels of DIV #a’s red background. But I don’t, unless I add overflow: auto or a border to DIV #a.

I know you’re all gonna laugh at me… but please let me know what to Google for to learn this strange behaviour!

Why won’t DIV #b push DIV #a up? I should see 20 pixels of DIV #a’s red background. But I don’t, unless I add overflow: auto or a border to DIV #a.

I know you’re all gonna laugh at me… but please let me know what to Google for to learn this strange behaviour!

No, this isn’t one of those silly easy questions, actually.

Hm, you’re probably hitting a few things here, but mostly “margin collapse”.

First, a is 100% wide by default but the only height it has is from #b’s content. Do your experiment with a set given height to both #a and #b, so you can see what’s happening easier.

Second, #a can’t get pushed “higher”… instead, you’re trying to push #b further down (because boxes are like soap bubbles… they’re already as close to the top left corner of their container (in this case, the body) as possible… all you can do most of the time is push them further away from that top left corner).

If you’re seeing some spacing between the edge of your browser and the #a box, that’s your browser’s default body padding showing up.

If you put this in front of your other CSS, #a should be hugging the very top and left in all browsers:
html, body {
margin: 0;
padding: 0;
}

(the point of doing this is just to make stuff the same cross-browser… it does not otherwise affect the behaviour of #a or #b)

Third, to see what you expected to see, instead of top margin on #b, give #a padding-top: 20px.

I actually do this on real pages: if I want some spacing between the top of a parent box and a child, I’ll use padding like this instead of margin.

Why?

Because of margin collapse. Google it as “css margin collapse” as it’s pretty important and also unintuitive (in my opinion, it always does exactly NOT what I’m expecting).

With margin-collapse, if we put a margin-top: 20px on the child #b, what you might see instead is #a looking like it has a top margin of 20px instead!

The margin of #b gets collapsed up to its parent #a, which is unintuitive and definitely not following Least Surprise : (

So after seeing my containers getting pushed down when I only had top margins on the children, I stopped using top margin like that.

To tell if it really is margin collapse in that scenario, you can use one of the defeaters: something to stop margin collapse. Adding a border (as you have found) or just 1px of padding, or setting overflow to anything other than “visible” (as you’ve also discovered) will stop margin collapse.

IE has some bugs with margin collapse. Floats for example are not supposed to get vertical margin collapse, but IE will do it (sometimes). Other times, regular static boxes who are supposed to get it, don’t in IE.

Hi,

I wrote a long piece on this for the Sitepoint reference which will save you the trouble of googling for more information :slight_smile:

It can be confusing at first and unintuitive but there are reasons why it is done this way.

I was actually looking for something really similar you had posted on search-this but instead I only found the IE-clearing post instead.

Thanks guys, I’m quickly printing this thread and the linked article so I can learn about it on the way home in the bus!

I appreciate the quick replies, it brightened this crappy monday, so thanks again :slight_smile:

That one’s here :slight_smile:

Thanks again guys… it’s amazing how you can dabble in this world for years, and then suddenly get stupified by something so simple!

Wait 'til you’ve been working in it for years, and get hit by something simple you never knew about!