CSS: Using Percent for Margin and Padding

For Mint.com, Jason Putorti and I are refactoring the way we do CSS graphing to support positive and negative values, where the bars are all scaled using percentages, so the design can change without any re-engineering. Hopefully, Jason will write a guest article about this soon, but until then, this development inspired todays article. In our graphs, the negative bar needed to be offset by the height of the positive region, and initially we thought to use the margin-top style to apply this offset. However, when we applied the style, using percentages, the resulting offset was drastically less than expected.

Doing a little research, I was reminded that when you use percents to apply the margin of an element, the browsers determine the actual size of the margin by multiply the percent against the width of the parent node (this is true for margin-top, -right, -bottom, and -left). It is not based on either the height or width of the element that the margin is applied to. So if you have the following DOM snippet:

Example 1: Margins

<div style="width: 20px">
<div id="temp1" style="margin-top: 50%">Test top</div>
<div id="temp2" style="margin-right: 25%">Test right</div>
<div id="temp3" style="margin-bottom: 75%">Test bottom</div>
<div id="temp4" style="margin-left: 100%">Test left</div>
</div>

Then you will have the following offsets:

Example 2: Margins Values

temp1.marginTop = 20px * 50% = 10px;
temp2.marginRight = 20px * 25% = 5px;
temp3.marginBottom = 20px * 75% = 15px;
temp4.marginLeft = 20px * 100% = 20px;

I then decided to research padding, for which I initially thought percentages would be relative to the element on which the padding is applied. However, I was surprised to relearn that the padding is also relative to the width of the applied elements parent node. So using percentages with padding works exactly as it does with margin.

Lastly, I was curious about the styles: top, right, bottom, and left, which you can apply to any non-statically positioned element. These styles are also applied, based on the parent node, however, they are different in that they are relative to the height instead of the width. For example:

Example 3: Positioned Elements

<div style="height: 100px; width: 50px">
<div id="temp1" style="position: relative; top: 50%">Test top</div>
<div id="temp2" style="position: relative; right: 25%">Test right</div>
<div id="temp3" style="position: relative; bottom: 75%">Test bottom</div>
<div id="temp4" style="position: relative; left: 100%">Test left</div>
</div>

In this case you will have the following offsets:

Example 4: Positioned Values

temp1.top = 100px * 50% = 50px;
temp2.right = 100px * 25% = 25px;
temp3.bottom = 100px * 75% = 75px;
temp4.left = 100px * 100% = 100px;

In all cases, you can use both positive and negative values. There is a special-case with positioned elements: when the parent element does not have a height, then percentage values are processed as auto instead. All this can be a bit confusing, but one just needs to remember that when using percentages with padding and margin it will be relative to the width of the parent node, while positioning a non-static element percentages will be applied relative to the height of the parent node.

I did most of my research today, on http://www.css3.com, a great resource for answering your CSS related questions. Here are the links to each of the properties mentioned above, in-case you want to learn more:

Margin-Top
Margin-Right
Margin-Bottom
Margin-Left

Padding-Top
Padding-Right
Padding-Bottom
Padding-Left

Top
Right
Bottom
Left