Background-color area changes depending on if a div has a border?

Look at the following code.

Exhibit B: (see attachment to a screen shot of it)

#second {
    border:1px solid #ff0000; 
    background-color:#ddeffc;
}

<div>First Div</div>
<div id="second">
<h1>Second Div</h1>
</div>

Now if you take away the border of the #second, the amount of area of #second that is colored changes:

Exhibit:A (see attachment)

#second {
    border:none; 
    background-color:#ddeffc;
}

<div>First Div</div>
<div id="second">
<h1>Second Div</h1>
</div>

I suppose my question is… don’t you think #second should maintain the same area of colored background, regardless if there is a border? Has this behavior caused you trouble? Or, is this just “the way it is”?

Thanks Ralph.M, it took me a few minutes, tell me if I understand this correctly:

Prior to #second having a border, h1 simply just fills up the div, but h1 hasn’t added its margins yet.

Then I add the border and h1 adds its margins creating a different size div.

So, from this I gather an element doesn’t add its default margins unless a new element is created around it?

Can’t see those images yet, but the border is added to the outside of the box (thus adding to the overall width and height) but I can’t say if this accounts for what you are describing. I wouldn’t think the colored bg area would change. Could it be a visual illusion?

EDIT: ah, I see. There are default top/bottom margins on the <h1> which stretch the #second div. When you remove the border, those margins hang outside of the box instead of being contained within it.

SO: If you want to keep that space inside the div, do something like this:

#second {
    border:none; 
    background-color:#ddeffc;
}


h1 {
  margin: 0;
  padding: 20px 0;
}

Note that browsers each apply their own default margins / paddings to various elements. SO: always specify the margins/paddings you want on elements, even if that’s 0. Otherwise you will get unexpected results.

No, not quite. If you serve just pure HTML, browser makes want that HTML to have a bit of style, so they set their own default styles on each element. For example, the h1 element might have 20px top and bottom margin.

So, the first thing many designers put in their style sheet is a “css reset”, like this:

html, body, div,
h1, h2, h3, h4, h5, h6, p, a, blockquote, pre, code, hr, img,
form, fieldset, legend, label, textarea, 
span, em, strong, sub, sup, cite,
table, tbody, td, tfoot, th, thead, tr, tt,
dl, dt, dd, ol, ul, li {
    margin: 0;
    padding: 0;
}

img {
    border: 0;
    vertical-align: bottom;
}

This overrides any browser styles that will make elements render in unwanted ways.

So, your h1 was being given default top and bottom margin by your browser. The rule of top and bottom margins is that they hang outside the boundaries of their container–UNLESS the container has a border, in which case the container contains the margins as well.

If this isn’t clear, read this article on collapsing margins.

Feel free to ask plenty of questions. We love to answer them!

thanks,
I’m working on understanding margin-collapsing now. I’m really trying to drill myself on some of the key concepts, so I can be a better programmer.