TL; DR
REM units are relative to the size defined in the parent element and not relative to the parent element of the selector where font-size
has been set.
What are REM and EM in CSS?
EM
" in is a scalable unit used in Web media. The value in is based on the width of the uppercase letter M. This value will be equal to the font-size
defined on the page or the browser default (probably 16px) if it has not been defined anywhere.
Example # 1:
body { font-size:62.5%; }
h1 { font-size: 2.4em; } /* =24px */
p { font-size: 1.4em; } /* =14px */
If the browser default value for font-size
is 16px, 62.5% of that is 10px, then 1em equals 10px. And because it is a scalable unit, 2.4em is 2.4x 10px (24px), as well as 1.4em is 14px.
One of the problems with using in font sizes is its cascading effect, which forces the developer to always set rules on the child selectors to reset them back to 1am.
In addition, font scaling with in is made up. A list within a list does not have 14px but 20px [context required] . Enter one more level and the font goes to measure 27px.
Example # 2
<style>
body { font-size: 100%; }
p, li { font-size: 0.75em; }
</style>
<p> 12px text </p>
<ul>
<li> 12px text
<ul>
<li> 9px text </li>
</ul>
</li>
</ul>
body { font-size: 100%; }
p, li { font-size: 0.75em; }
<p> 12px text </p>
<ul>
<li> 12px text
<ul>
<li> 9px text </li>
</ul>
</li>
</ul>
These problems can be bypassed by declaring on any child element that it uses 1em, avoiding the unwanted cascading effect.
CSS3 now has rem that prevents this behavior.
REM
REM is an acronym for Root EM . REM units allow you to set a primary value in the HTML element and then use values in the subsequent elements for that main unit.
The rem unit is also scalable, but relative to specific elements on the page, without affecting the other elements
Examples:
html { font-size: 62.5%; }
body { font-size: 1.4rem; } /* =14px */
h1 { font-size: 2.4rem; } /* =24px */
All recent browsers support REM units. For browsers that do not support it we have to use fallback option in pixels (px):
html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */
In the second example (with HTML) change the setting to:
p, li
{
font-size: 12px;
font-size: 0.75rem;
}
Ensures that the < li & gt: children elements remain with 12px.
body { font-size: 100%; }
p, li { font-size: 0.75rem; }
<p> 12px text </p>
<ul>
<li> 12px text
<ul>
<li> 12px text </li>
</ul>
</li>
</ul>
A third example , a little differentiated and more extended, involving paddings . p>
In the first group of nested DIVs, the computed values are:
20px
48px
72px
108px
The first DIV receives the global value of 20px for all DIVs (20px). Without a global value, the DIV does not have padding (see the console populated by JS attached to the snippet ).
From the second on the values become 2em , or 2x, the computed value of the previous element, respecting the box-model :
20px
48px = 20px + 4px (border) x 2
72px = 20px + 4px (border) + 48px (parent element)
108px = 20px + 4px (border) + 72px (parent-element)
This demonstrates well the cumulative cascading effect I said.
In the second group of nested DIVs, the first one reports the same 20px and all the paddings computed from the nested DIVs report 32px .
But why if padding is already 32px and the "global" is 20px?
Because ... it's relative ... to font-size
. Try changing the padding of the HTML selector to any value and you will see that, except for the HTML selector of course, all nested DIVs still report the 32px / p>
Now we change the value of font-size
, say ... 20px , for example.
The first DIV continues reporting the global 20px and all other DIVs report 40px , that is 2em , or 2x < strong> 20px defined in font-size
.
Source # 1: CSS-Stars
Source # 2: SitePoint