I don’t think this happens very often. To be honest, I don’t think I’ve ever used a percentage value on a top padding/margin, or a bottom padding/margin value. Even for height values, I may have used a 100% value for a hack, but nothing else.

Nonetheless, using percentages on those vertical parts of a page are somewhat different in the way they are calculated, compared to other properties that take percentage values.

Here are the rules for percentages on vertical items:

A percentage value on top/bottom padding or margins is relative to the width of the containing block

A percentage value on height is relative to the height of the containing block (same for min/max height)

A Percentage value on top and bottom values for a positioned element is relative to the height of the containing block (hat tip to Hashem Qolami for the reminder)

and values for a positioned element is relative to the height of the containing block (hat tip to Hashem Qolami for the reminder) Percentage values are not allowed on border widths (not even left and right)

And here’s a CodePen showing this in action, using top/bottom padding/margins set with percentages, along with a set-width container:

See the Pen Vertical Percentages by Louis Lazaris (@impressivewebs) on CodePen

Notice it uses jQuery to calculate and display the total height of the element including padding. I’ve intentionally used a value of 1000px for the container and 100×100 for the element itself, just to make any percentage calculations simpler to envision.

As it stands, the total height is 300px — which is 100px (as defined in the CSS) plus 100px of top padding (which is 10% of 1000px of the container width) and 100px of bottom padding (same calculation as top).

And keep in mind that the calculations would be vastly different if I just threw some content in the boxes and let the container element expand without a set width. Then the container’s width would be dependent on the window size (or iframe size, in the case of a code embed like above).

Also, if I was using box-sizing: border-box , that would affect the total height value that’s displayed.

Why Relative to Container Width?

In thinking about why vertical padding and margin percentage values are relative to the containing block’s width, my guess would be that this is simply much easier to control.

Width values are commonly set, whereas heights are usually just dependent on content. In fact, I would go as far as to say it’s usually bad practice to define a height on an element ( min-height is fine though). So if you want to actually set vertical margin/padding percentages, it would be unintuitive to set these relative to an arbitrary content-based height. Instead, it’s much easier to do the calculation based on width — because it’s much more likely that a width is being set explicitly.

Of course, I don’t know if this is the case. I can’t seem to find an explanation for this anywhere, so if anyone who works on the specs has a more technical answer, then please comment and I’ll update the article accordingly.

These links on my CSS Values reference have external links to MDN and W3C, so you can look those up to see what the spec says: