A unidade em é um dos pilares dos layouts elásticos.
Seu valor é definido pelo tamanho da fonte do elemento em que você está trabalhando (ou seu elemento pai), portanto, se esse valor mudar por qualquer motivo (ou seja, o usuário aumentar ou diminuir o zoom), todos os tamanhos definidos em em serão alterados de acordo.
Então, o que é um em?
Por padrão, em um navegador da web, 1em é igual a 16px.
Por padrão? Quer dizer que posso mudar isso?
Claro. Você apenas tem que definir o tamanho da fonte do seu elemento html como 62,5%. Isso calcula para 10 px, tornando muito mais fácil definir o resto dos seus tamanhos no ems:
html {
font-size: 62.5%; /* 10px /
}
p {
font-size: 1.2em; / 12px */
}
</code>
</pre>
Amazing! So what's wrong with ems?
Nothing really, BUT there's a risk that you might want to be aware of: nesting stuff.
Let's take a classic example of a dropdown menu, where you'll have markup with this pattern: ul > li > ul > li
I might want to have all my li elements to have a font-size of 14px, so I'd do something like this:
li {
font-size: 1.4em;
}
</code>
</pre>
Now, for my top level list items this would work as expected since their parent font size is 10px, so 1.4em = 14px. Perfect.
But now the child list items have a parent font-size of 14px instead of 10px, so now 1.4em = 19.6px. Not really what we wanted.
The solution for this is to redefine the child li:
li {
font-size: 1.4em; /* 14px */
}
li li {
font-size: 1em; /* 14px */
}
</code>
</pre>
Not really the type of code I want on my css... and that's where the rem unit comes in.
What's a rem?
A rem unit (root em</code>) follows the same concept as the em, but with a small big difference. Instead of having its value defined by its parent's font-size, it takes the value from the root element's font-size; that is, in a HTML document, the html element.
Let's code our example dropdown with rems:
html {
font-size: 62.5%; /* 10px /
}
li {
font-size: 1.4rem; / 14px */
}
</code>
</pre>
Now it doesn't matter how deep I'd go nesting stuff, 1rem will always be equal to 10px.
What about browser support?
It's pretty good actually. Every modern browser support rems, including IE9.
If you're supporting older versions of IE, a good fallback will be to define your font sizes in px before you define them in rems, this way every browser will use the units they understand.