Gostaria de elogiar a resposta de josh3736 por fornecer um excelente contexto histórico. Embora seja bem articulado, o cenário do CSS mudou nos quase cinco anos desde que essa pergunta foi feita. Quando essa pergunta foi feita, px
foi a resposta correta, mas isso não é mais verdade hoje.
tl; dr: userem
Visão geral da unidade
Historicamente, as px
unidades geralmente representavam um pixel do dispositivo. Com dispositivos com densidade de pixels cada vez maior, isso não vale mais para muitos dispositivos, como o Retina Display da Apple.
rem
unidades representam a r oot em tamanho. É o que font-size
quer que seja :root
. No caso do HTML, é o <html>
elemento; para SVG, é o <svg>
elemento O padrão font-size
em todos os navegadores * é 16px
.
No momento da redação deste artigo, rem
é suportado por aproximadamente 98% dos usuários . Se você estiver preocupado com esses outros 2%, lembrarei que as consultas de mídia também são suportadas por aproximadamente 98% dos usuários .
Sobre o uso px
A maioria dos exemplos de CSS na Internet usa px
valores porque eles eram o padrão de fato. pt
, in
e várias outras unidades poderiam ter sido usadas na teoria, mas elas não lidavam bem com valores pequenos, pois você rapidamente precisava recorrer a frações, que eram mais longas para digitar e mais difíceis de raciocinar.
Se você queria uma borda fina, com a qual px
você poderia usar 1px
, pt
precisaria usar 0.75pt
para obter resultados consistentes, e isso não é muito conveniente.
Sobre o uso rem
rem
O valor padrão de 16px
não é um argumento muito forte para seu uso. Escrever 0.0625rem
é pior do que escrever 0.75pt
, então por que alguém usaria rem
?
Há duas partes em rem
vantagem sobre outras unidades.
- As preferências do usuário são respeitadas
- Você pode alterar o
px
valor aparente rem
para o que quiser
Respeitando as preferências do usuário
O zoom do navegador mudou muito ao longo dos anos. Historicamente, muitos navegadores apenas aumentavam de tamanho font-size
, mas isso mudou muito rapidamente quando os sites perceberam que seus belos designs perfeitos em pixels estavam quebrando sempre que alguém aumentava ou diminuía o zoom. Nesse ponto, os navegadores escalam a página inteira, para que o zoom baseado em fonte fique fora de cena.
Respeitar os desejos de um usuário não está fora de cena. Só porque um navegador está definido como 16px
padrão, não significa que nenhum usuário possa alterar suas preferências 24px
ou 32px
corrigir uma visão subnormal ou baixa visibilidade (brilho da tela). Se você basear suas unidades rem
, qualquer usuário com tamanho de fonte mais alto verá um site proporcionalmente maior. As bordas serão maiores, o preenchimento será maior, as margens serão maiores, tudo aumentará fluidamente.
Se você basear suas consultas de mídia rem
, também poderá garantir que o site que seus usuários visualizem se encaixa na tela deles. Um usuário font-size
definido como 32px
em um 640px
navegador amplo, efetivamente verá seu site como mostrado a um usuário 16px
em um 320px
navegador amplo. Não há absolutamente nenhuma perda para o RWD no uso rem
.
Alteração do px
valor aparente
Porque rem
é baseado no font-size
do :root
nó, se você quiser mudar o que 1rem
representa, tudo que você tem a fazer é mudar o font-size
:
:root {
font-size: 100px;
}
body {
font-size: 1rem;
}
<p>Don't ever actually do this, please</p>
Faça o que fizer, não defina o :root
elemento de font-size
um px
valor.
Se você definir o font-size
sobre html
a um px
valor, você desintegradas as preferências do usuário sem uma maneira de recuperá-los.
Se você deseja alterar o valor aparente de rem
, use %
unidades.
A matemática para isso é razoavelmente direta.
O tamanho aparente da fonte de :root
é 16px
, mas digamos que queremos alterá-lo para 20px
. Tudo o que precisamos fazer é multiplicar 16
por algum valor para obter 20
.
Configure sua equação:
16 * X = 20
E resolva para X
:
X = 20 / 16
X = 1.25
X = 125%
:root {
font-size: 125%;
}
<p>If you're using the default font-size, I'm 20px tall.</p>
Fazer tudo em múltiplos de 20
não é tão bom assim, mas uma sugestão comum é tornar o tamanho aparente rem
igual a 10px
. O número mágico para isso é 10/16
qual é 0.625
, ou 62.5%
.
:root {
font-size: 62.5%;
}
<p>If you're using the default font-size, I'm 10px tall.</p>
O problema agora é que o padrão font-size
para o resto da página é conjunto muito pequeno, mas há uma correção simples para isso: Definir um font-size
em body
usar rem
:
:root {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
}
<p>I'm the default font-size</p>
É importante observar que, com esse ajuste, o valor aparente de rem
é o 10px
que significa que qualquer valor no qual você possa ter escrito px
pode ser convertido diretamente ao rem
inserir uma casa decimal.
padding: 20px;
torna-se em
padding: 2rem;
O tamanho aparente da fonte que você escolher depende de você; portanto, se você quiser, não há motivo para não usá-lo:
:root {
font-size: 6.25%;
}
body {
font-size: 16rem;
}
e tem 1rem
igual 1px
.
Então, aí está, uma solução simples para respeitar os desejos do usuário, evitando também complicar demais o seu CSS.
Espere, então qual é o problema?
Eu tinha medo que você pudesse perguntar isso. Por mais que eu queira fingir que rem
é mágico e resolve tudo, ainda existem alguns problemas a serem observados. Nada de acordo na minha opinião , mas vou chamá-los para que você não possa dizer que não avisei.
Consultas de mídia (uso em
)
Um dos primeiros problemas com os quais você se depara rem
envolve consultas de mídia. Considere o seguinte código:
:root {
font-size: 1000px;
}
@media (min-width: 1rem) {
:root {
font-size: 1px;
}
}
Aqui, o valor das rem
alterações depende da aplicação da consulta à mídia, e a consulta à mídia depende do valor de rem
, então o que está acontecendo?
rem
nas consultas de mídia, usa o valor inicial de font-size
e não deve (consulte a seção Safari) levar em consideração as alterações que possam ter ocorrido font-size
no :root
elemento. Em outras palavras, seu valor aparente é sempre 16px
.
Isso é um pouco chato, porque significa que você precisa fazer alguns cálculos fracionários, mas eu descobri que as consultas de mídia mais comuns já usam valores múltiplos de 16.
| px | rem |
+------+-----+
| 320 | 20 |
| 480 | 30 |
| 768 | 48 |
| 1024 | 64 |
| 1200 | 75 |
| 1600 | 100 |
Além disso, se você estiver usando um pré-processador CSS, poderá usar mixins ou variáveis para gerenciar suas consultas de mídia, o que ocultará completamente o problema.
Safári
Infelizmente, existe um bug conhecido no Safari, em que alterações no :root
tamanho da fonte realmente alteram os rem
valores calculados para os intervalos de consulta de mídia. Isso pode causar um comportamento muito estranho se o tamanho da fonte do :root
elemento for alterado em uma consulta de mídia. Felizmente, a correção é simples: use em
unidades para consultas de mídia .
Troca de Contexto
Se você alternar entre vários projetos diferentes, é bem possível que o tamanho aparente da fonte rem
tenha valores diferentes. Em um projeto, você pode estar usando um tamanho aparente de 10px
onde, em outro projeto, o tamanho aparente pode estar 1px
. Isso pode ser confuso e causar problemas.
Minha única recomendação aqui é manter 62.5%
a conversão rem
para um tamanho aparente de 10px
, porque isso tem sido mais comum em minha experiência.
Bibliotecas CSS compartilhadas
Se você estiver escrevendo CSS que será usado em um site que você não controla, como para um widget incorporado, não há realmente uma boa maneira de saber qual tamanho aparente rem
terá. Se for esse o caso, fique à vontade para continuar usando px
.
Se você ainda deseja usar rem
, considere liberar uma versão Sass ou LESS da folha de estilo com uma variável para substituir a escala pelo tamanho aparente de rem
.
* Não quero assustar ninguém rem
, mas não pude confirmar oficialmente que todos os navegadores usam 16px
por padrão. Veja bem, existem muitos navegadores e não seria tão difícil para um navegador divergir um pouco, digamos 15px
ou assim 18px
. Nos testes, no entanto, eu não vi um único exemplo em que um navegador usando configurações padrão em um sistema usando configurações padrão tivesse outro valor além de 16px
. Se você encontrar um exemplo, compartilhe comigo.