Why are margin/padding percentages in CSS always calculated against width?

mqp picture mqp · Jun 12, 2012 · Viewed 66.4k times · Source

If you look at the CSS box model spec, you'll observe the following:

The [margin] percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1. (emphasis mine)

This is indeed true. But why? What on earth would compel anyone to design it this way? It's easy to think of scenarios where you want, e.g. a certain thing to always be 25% down from the top of the page, but it's hard to come up with any reason why you would want vertical padding to be relative to the horizontal size of the parent.

Here's an example of the phenomenon I'm referring to:

<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
  This div is 200x800.
  <div style="border: 1px solid blue; margin: 10% 0 0 10%;">
    This div has top-margin of 10% and left-margin of 10% with respect to its parent.
  </div>
</div>

http://jsfiddle.net/8JDYD/

Answer

Ryan Kinal picture Ryan Kinal · Jun 12, 2012

Transferring my comment to an answer, because it makes logical sense. However, please note that this is unfounded conjecture. The actual reasoning of why the spec is written this way is still, technically, unknown.

Element height is defined by the height of the children. If an element has padding-top: 10% (relative to parent height), that is going to affect the height of the parent. Since the height of the child is dependent on the height of the parent, and the height of the parent is dependent on the height of the child, we'll either have inaccurate height, or an infinite loop. Sure, this only affects the case where offset parent === parent, but still. It's an odd case that is difficult to resolve.

Update: The last couple sentences may not be entirely accurate. The height of the leaf element (child with no children) has an effect on the height of all elements above it, so this affects many different situations.