From the W3C specification :
The percentage is calculated by the width of the generated block containing the block. Note that this is true for margin-top and margin-bottom. If the width of this block depends on this element, then the final layout is undefined in CSS 2.1.
There are two good reasons for aligning vertical fields with the width of the containing block:
Horizontal and vertical consistency
There is, of course, a reduction property that allows you to specify a margin for all four sides of a block:
margin: 10%;
It expands to:
margin-top: 10%; margin-right: 10%; margin-bottom: 10%; margin-left: 10%;
Now, if you wrote one of the above, you probably expect the fields on all four sides of the block to be the same size, right? But if margin-left and margin-right were based on the width of the container, and margin-top and margin-bottom were based on its height, then they were usually different!
Avoiding Circular Dependence
CSS displays content in blocks vertically down the page, so the width of the block is usually dictated by the width of its parent. In other words, you can calculate the width of a block without worrying about what's inside that block.
Block height is another matter. Usually the height depends on the total height of its contents. Change the height of the content and change the height of the block. See the problem?
To get the height of the content, you need to know the top and bottom fields that apply to it. And if these fields depend on the height of the parent block, you have problems because you cannot calculate one without knowing the other!
The base of the vertical margins across the width of the container violates this cyclic dependence and allows you to lay out the page.
Example:
Here is the fiddle . And the code:
HTML
<div class="container"> <p id="element"> Some Cool content</p> </div> <p> MORE TEXT </p>
CSS
.container { background: lightblue; padding: 10px; height: 100px; width: 500px; } p { display: block; border: 1px solid red; margin-top: 50%; }
Js
window.onload = function(evt) { var element = document.getElementById("element"), style = element.currentStyle || window.getComputedStyle(element); element.textContent = "the margin-top is : " + style.marginTop; };