Objective
To illustrate the CSS box model and explain the difference between setting margin and padding properties on a block-level element.
Box Diagram
Figure 1. Nested boxes: demo_container → demo_box → demo_content
Markup
This is a set of three nested divs, but focus on the middle one, called demo_box:
<div id="demo_container">
<div id="demo_box">
<div id="demo_content">
the innermost rectangle is 300px wide
</div>
</div>
</div>
CSS
Note especially the margin and padding rules on demo_box:
#demo_container {
background-color:#F6F6F6;
border:1px solid #DDD;
margin:1.5em 0;
width:380px;
}
#demo_box {
background-color:#EEE;
border:1px dashed #999;
height:200px;
margin:20px;
padding:20px;
width:300px;
}
#demo_content {
background-color:#FFF;
border:1px solid #DDD;
height:100%;
width:100%;
}
Explanation
The dashed line is the border of demo_box:
- it’s margin is the very light-grey area between the dashed line and the containing (outer) box
- It’s padding is the slightly darker grey area between the dashed line and the contained (inner) box
In this example both margins and padding are set to 20px. On block level elements, padding does not collapse but margins do collapse.
This means that if you placed another identical box, say demo_box2, after demo_box, the dashed border on the second box would be only 20px below the dashed border on the first (not 40px, even though the bottom margin on the top box and the top margin on the bottom one are both set to 20px):
Figure 2. Nested boxes with demo_box and demo_box2 divs
If you wanted to close the gap between the boxes completely you would remove both of the margins where they meet. If you wanted more than a 20px separation between them you could increase one or both of them to the desired amount.
Also note that the width of demo_box is 300px plus the left and right padding, plus the left and right margins. So the outer box is actually 380px wide. (IE6 got this famously wrong, which has resulted in much fun for front-end developers ever since.)
Finally, the innermost box is set to a width of 100% which means that it expands to fill it's containing element, not the width of the viewport (in this case 300px, since that is the width of demo_box.
Conclusion
When faced with the choice of setting margins or padding, sometimes it doesn’t matter, though it usually does in some way. But even though there are implications, you often don’t need both. My approach is to imagine where I would want the border to be if I turned it on for that element (even if I’m not going to), and then decide from there.
(Note that the rules are different for inline elements (e.g. a, em, span, strong), which do not observe the same top and bottom margin rules—for these use line-height instead.)