CSS supports multiple unit forms, such as percentage, px, pt, rem, etc. Percentage and px are commonly used units. With the popularity of mobile and responsive design, rem, vh, and vw have also become widely used.
Today I came across two questions about percentage calculation on the SegmentFault community. One was, when using percentage in translate, which DOM element's size is it calculated relative to? The other was, when using percentage in padding, margin, etc., how are percentages converted to px?
For the first one, the movement distance is calculated based on the size of the element itself:
[The percentage] refer[s] to the size of the element's box
For example: in the case of not knowing the element's width and height, center the element horizontally and vertically.
Create a div with class name wrapper and set its style.
.wrapper {
padding: 20px;
background:orange;
color:#fff;
position:absolute;
top:50%;
left:50%;
border-radius: 5px;
-webkit-transform:translate(-50%,-50%);
-moz-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
}
For the second, I thought the browser should convert percentage to px according to CSS rules, but how exactly is it calculated?
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>
The obtained offset is as follows:
temp1.marginTop = 20px * 50% = 10px; temp2.marginRight = 20px * 25% = 5px; temp3.marginBottom = 20px * 75% = 15px; temp4.marginLeft = 20px * 100% = 20px;
Then, I also tested padding. I originally thought the value of padding would be calculated based on the element to which the property was applied, but to my surprise, padding is also calculated based on the width of the parent element to which the property is applied, consistent with margin behavior. (One more note: when setting an element's width as a percentage, it is relative to the width of the parent container; the vertical percentage of an element is also relative to the container's width, not its height.)
But there is a pitfall: the above is all for non-positioned elements. Being curious, I was also curious: for non-statically positioned elements, how are the percentage values of top, right, bottom, and left calculated?
Example 2: 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>
The obtained offset is as follows:
temp1.top = 100px * 50% = 50px; temp2.right = 100px * 25% = 25px; temp3.bottom = 100px * 75% = 75px; temp4.left = 100px * 100% = 100px;
For positioned elements, these values are also relative to the parent element, but unlike non-positioned elements, they are relative to the parent element's height rather than width.
when the parent element does not have a height, then percentage values are processed as auto instead
Although it's a bit confusing, just remember: for margin and padding, percentages are calculated according to the parent element's width; for positioned elements, they are calculated according to the parent element's height.