em ou rem: qual será a escolha certa?

Escolher entre em ou rem é uma das dúvidas mais comuns de quem trabalha com CSS, porque a unidade de medida define como cada elemento reage ao tamanho da fonte e da tela. Essa escolha afeta diretamente a responsividade e a acessibilidade da página.

O CSS oferece medidas absolutas, como o px, e medidas relativas, como o em e o rem. Mesmo quem já entende a diferença entre unidades relativas e absolutas costuma travar na mesma pergunta: devo usar em ou rem?

Neste artigo, você vai ver como cada unidade calcula o valor final, onde cada uma brilha e quais armadilhas evitar. Ao final, a decisão entre em ou rem deixa de ser um palpite e passa a seguir critérios claros.

O que são em e rem no CSS

As unidades em e rem são medidas relativas e totalmente flexíveis. Em vez de representar um valor fixo, que nunca muda, elas calculam o tamanho final a partir de uma fonte de referência.

Na prática, o navegador converte essas unidades para pixels no momento da renderização. Assim, você escreve um valor proporcional e o navegador resolve o número exato de acordo com o contexto.

Veja um exemplo simples com em aplicado ao padding de um parágrafo:

p {
  font-size: 16px;
  /* 1em aqui equivale a 16px, a fonte do próprio parágrafo */
  padding: 1em;
}

Nesse caso, o espaçamento interno acompanha o tamanho da fonte do parágrafo. Por isso, se a fonte crescer, o padding cresce junto, sem nenhuma alteração extra no código.

O mesmo exemplo também funciona com rem:

p {
  font-size: 16px;
  /* 1rem aqui equivale à fonte do elemento raiz (html) */
  padding: 1rem;
}

A diferença entre em ou rem está, portanto, na referência usada para o cálculo. Enquanto o em olha para o contexto do próprio elemento, o rem olha sempre para a raiz do documento.

Segundo a documentação de unidades de comprimento da MDN, essa distinção é exatamente o que separa as duas unidades. A seguir, vamos detalhar cada uma delas.

Como o em calcula o tamanho

O em representa o tamanho de fonte calculado do elemento. Quando você usa em na própria propriedade font-size, ele passa a representar o tamanho de fonte herdado do elemento pai.

Imagine uma estrutura HTML com um elemento pai e um elemento filho:

<div class="container">
  <div class="description">
    <p>HTML course</p>
  </div>
</div>

Aqui, a classe container é o elemento pai. Logo abaixo, a classe description envolve um parágrafo com o texto do curso.

Agora observe o CSS:

.container {
  font-size: 16px;
}

.description {
  /* herda 16px do pai e multiplica por 1 */
  font-size: 1em;
}

Como o font-size da classe container vale 16px, o 1em da classe description também resulta em 16px. Em outras palavras, o em multiplica o valor herdado pelo número informado.

O cálculo segue sempre a mesma lógica:

  • 1em corresponde a 100% da fonte herdada, ou seja, 16px.
  • 2em corresponde a 200% da fonte herdada, ou seja, 32px.
  • 0.5em corresponde a 50% da fonte herdada, ou seja, 8px.

Esse raciocínio precisa ficar claro, porque ele explica quase todos os comportamentos inesperados do em. Afinal, cada valor depende de onde o elemento está na árvore do documento.

O em em outras propriedades

Existe um detalhe que muita gente ignora. Quando o em aparece em propriedades como padding, margin ou width, ele usa a fonte do próprio elemento, e não a do pai.

Observe o exemplo:

.card {
  font-size: 20px;
  /* 1em = 20px, a fonte do próprio .card */
  padding: 1em;
}

Nesse caso, o padding vale 20px, porque o .card define a própria fonte. Então, o espaçamento acompanha o texto do componente, e não o texto do elemento externo.

Esse comportamento é justamente o que torna o em útil para componentes. Se você aumentar a fonte de um botão, o espaçamento interno cresce na mesma proporção.

Como o rem calcula o tamanho

O rem calcula da mesma forma que o em, porém com uma referência diferente. O "r" de rem significa root, ou seja, raiz.

A raiz do documento é o elemento html. Portanto, o rem sempre multiplica o valor informado pelo font-size definido no html, independentemente de onde o elemento esteja.

Caso você não defina nenhum tamanho no html, o navegador aplica o padrão dele. Segundo a MDN, o padrão mais comum é 16px, mas o usuário pode alterar esse valor nas configurações do navegador.

Um ponto importante: o rem não olha para o body. Mesmo que você defina uma fonte no body, o cálculo do rem continua partindo do html.

html {
  /* a raiz define a referência do rem */
  font-size: 16px;
}

body {
  /* isso não altera o valor de 1rem */
  font-size: 20px;
}

h1 {
  /* 2rem = 32px, calculado a partir do html */
  font-size: 2rem;
}

Dessa forma, um 2rem resulta em 32px em qualquer ponto da página. Essa previsibilidade é o principal argumento a favor do rem.

Diferenças entre em ou rem na prática

Depois de entender o cálculo, fica mais fácil comparar as duas unidades lado a lado. A tabela abaixo resume os pontos principais.

Característica em rem
Referência em font-size Fonte herdada do pai Fonte do html
Referência em outras propriedades Fonte do próprio elemento Fonte do html
Efeito em elementos aninhados Acumula a cada nível Não acumula
Previsibilidade Depende do contexto Igual em toda a página
Uso mais comum Componentes e espaçamentos proporcionais Tipografia e escala global

Na prática, a pergunta sobre em ou rem se resume a uma decisão de referência. Você quer que o valor acompanhe o componente ou que ele acompanhe a página inteira?

O efeito cascata do em

O maior risco do em aparece em elementos aninhados. Como cada filho herda a fonte do pai, os valores se multiplicam a cada nível da árvore.

Veja um exemplo com listas:

.menu {
  font-size: 16px;
}

.menu ul {
  /* cada nível multiplica a fonte do nível anterior */
  font-size: 1.2em;
}
<nav class="menu">
  <ul>
    <li>Home
      <ul>
        <li>Products
          <ul>
            <li>Details</li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>

No primeiro nível, a lista fica com 19,2px. Em seguida, o segundo nível sobe para 23,04px, e o terceiro chega a 27,65px.

Esse efeito cascata é chamado de composição, ou compounding em inglês. Ele surge sem que ninguém perceba e costuma gerar textos gigantes em menus e comentários aninhados.

Com rem, o mesmo código manteria todos os níveis em 19,2px. Isso acontece porque o cálculo sempre volta para a raiz, e não para o nível anterior.

Por isso, quando você estiver em dúvida entre em ou rem para fontes de elementos que se repetem dentro de si mesmos, prefira o rem. Assim, a composição simplesmente não acontece.

Por que utilizar rem

Use o rem quando você precisa da certeza de que tudo na página parte do mesmo tamanho base. Esse é o motivo de o rem ser tão utilizado para tamanhos de fonte.

Sempre que a tipografia da aplicação precisa seguir uma escala única, o rem resolve o problema. Você define a referência uma vez, no html, e todos os títulos e parágrafos acompanham essa decisão.

Outro ponto importante é a facilidade de depuração. Se algum texto aparecer com tamanho estranho, você sabe imediatamente que a origem está na configuração da raiz, e não em uma herança escondida.

O rem também simplifica a criação de uma escala tipográfica:

:root {
  font-size: 100%;
}

h1 { font-size: 2.5rem; }   /* 40px com o padrão de 16px */
h2 { font-size: 2rem; }     /* 32px */
h3 { font-size: 1.5rem; }   /* 24px */
p  { font-size: 1rem; }     /* 16px */
small { font-size: 0.875rem; } /* 14px */

Repare que a raiz usa 100% em vez de um valor em pixels. Com isso, a página respeita o tamanho que o usuário configurou no navegador.

Por que utilizar em

O em tem um uso mais aberto, porque se refere ao contexto do elemento. Sempre que você precisa que um valor siga as proporções do componente, o em é a escolha natural.

Além disso, ele evita repetir valores em pixels. Você define a fonte uma vez no componente e, se precisar mudar, altera apenas esse ponto, sem revisar cada espaçamento.

Um exemplo clássico é o botão com tamanhos diferentes:

.button {
  font-size: 1rem;
  /* o espaçamento acompanha a fonte do próprio botão */
  padding: 0.5em 1em;
  border-radius: 0.25em;
}

.button-large {
  /* basta mudar a fonte para escalar todo o botão */
  font-size: 1.25rem;
}

Nesse caso, o .button-large cresce de forma proporcional, inclusive no padding e no border-radius. Então, você mantém o desenho do componente com uma única alteração.

Esse exemplo também mostra que a escolha entre em ou rem não precisa ser exclusiva. A fonte usa rem para seguir a escala global, enquanto o espaçamento usa em para seguir o componente.

Em ou rem e a acessibilidade

Muitos usuários aumentam o tamanho padrão da fonte no navegador para ler melhor. A MDN alerta que unidades absolutas podem causar problemas de acessibilidade, porque não acompanham essas preferências.

Por esse motivo, a recomendação é preferir unidades relativas, como em e rem, no font-size. Assim, quando o usuário escolhe 20px como padrão, o 1rem passa a valer 20px automaticamente.

As diretrizes de acessibilidade do W3C também apontam nessa direção. O critério 1.4.4 da WCAG exige que o texto possa ser ampliado até 200% sem perda de conteúdo ou funcionalidade.

Um erro comum é fixar a fonte do html em pixels:

/* evite: ignora a preferência do usuário */
html {
  font-size: 16px;
}

/* prefira: respeita a configuração do navegador */
html {
  font-size: 100%;
}

Quando a raiz usa pixels, o rem perde parte do benefício de acessibilidade. Afinal, toda a escala passa a partir de um valor que o usuário não consegue alterar pelas configurações de fonte.

A técnica dos 62,5%

Alguns projetos definem a fonte do html como 62.5%. Com o padrão de 16px, isso transforma a referência em 10px e facilita as contas.

html {
  /* 62.5% de 16px = 10px */
  font-size: 62.5%;
}

body {
  /* volta o texto para 16px */
  font-size: 1.6rem;
}

h1 {
  /* 24px */
  font-size: 2.4rem;
}

Dessa forma, 2.4rem vira 24px e 1.4rem vira 14px, sem calculadora. Ainda assim, a técnica exige disciplina, porque qualquer elemento sem fonte definida herda os 10px da raiz.

Como a técnica usa porcentagem, ela continua respeitando a configuração do usuário. Por outro lado, muitos times preferem manter 100% e conviver com valores como 1.5rem para evitar surpresas.

Em ou rem em media queries

As media queries têm uma regra especial. Nelas, tanto o em quanto o rem usam o tamanho de fonte inicial do navegador, e não o valor que você definiu no html.

/* 48em = 768px quando o padrão do navegador é 16px */
@media (min-width: 48em) {
  .layout {
    display: grid;
    grid-template-columns: 1fr 3fr;
  }
}

Por isso, em media queries a escolha entre em ou rem tem pouco impacto prático. O ganho real está em usar uma unidade relativa, porque o ponto de quebra acompanha o zoom de texto do usuário.

Se você quer se aprofundar nesse tema, vale ler o guia básico sobre media query. Ele mostra como montar pontos de quebra para diferentes tamanhos de tela.

Quando escolher em ou rem

Com tudo isso em mente, dá para montar um guia rápido de decisão. Ele não substitui o bom senso, mas cobre a maioria dos casos do dia a dia.

Prefira rem quando:

  • Você define tamanhos de fonte da tipografia global.
  • O elemento pode aparecer aninhado em si mesmo, como menus e comentários.
  • Você quer espaçamentos consistentes entre seções da página.
  • A previsibilidade importa mais do que a proporção local.

Prefira em quando:

  • O espaçamento deve acompanhar a fonte do próprio componente.
  • Você cria variações de tamanho de um mesmo componente, como botões e badges.
  • Ícones precisam acompanhar o tamanho do texto ao lado.
  • Bordas arredondadas devem escalar junto com o elemento.

Na dúvida entre em ou rem, comece pelo rem. Em seguida, troque para em apenas nos pontos em que a proporção do componente for o comportamento desejado.

Essa abordagem combina bem com outras técnicas de layout. Por exemplo, o artigo Pense de forma responsiva e o guia sobre como começar com o Flexbox completam esse raciocínio.

Erros comuns ao usar em ou rem

Alguns deslizes aparecem com frequência em projetos reais. Conhecer cada um deles economiza horas de depuração.

O primeiro é achar que o rem olha para o body. Como vimos, a referência é sempre o html, então alterar a fonte do body não muda o valor de 1rem.

O segundo é usar em em fontes de componentes reutilizáveis sem considerar onde eles serão inseridos. Nesse caso, o mesmo componente pode ficar maior ou menor dependendo do contêiner.

O terceiro é fixar a raiz em pixels e anular a preferência do usuário. Mesmo usando rem em todo o projeto, a página deixa de responder ao ajuste de fonte do navegador.

Por fim, existe o erro de misturar unidades sem critério. Quando cada desenvolvedor escolhe livremente, o código fica difícil de manter, então vale registrar a convenção do time.

O que podemos concluir sobre em ou rem

O em e o rem têm basicamente a mesma função, porém com referências diferentes. Um olha para o contexto do elemento, enquanto o outro olha sempre para a raiz do documento.

Usar as duas unidades traz praticidade, porque você deixa de memorizar quantos pixels cada componente tem. Basta pensar na relação proporcional e deixar o navegador calcular.

O rem é a escolha mais comum para fontes, já que parte da raiz html e mantém a escala estável. Já o em tem um leque mais aberto e funciona muito bem para componentes, espaçamentos e ícones.

Portanto, a resposta para em ou rem raramente é uma só. Na maioria dos projetos, as duas convivem, cada uma no papel em que entrega mais previsibilidade.

Vídeo no YouTube

Se você prefere aprender assistindo, o vídeo abaixo explica a diferença entre as duas unidades.

Curso gratuito balta.io: crie sites responsivos

Para colocar esses conceitos em prática, o balta.io oferece um curso gratuito sobre criação de sites responsivos.

Banner de divulgação do curso gratuito do balta.io sobre criação de sites responsivos com HTML e CSS, onde unidades como em ou rem fazem parte do layout
Curso gratuito do balta.io para aprender a criar sites responsivos.

Obrigado pela leitura! Espero que você tenha gostado do conteúdo e até a próxima.

FAQ

Qual a diferença entre em ou rem?

O em usa como referência a fonte do contexto do elemento, enquanto o rem usa sempre a fonte do elemento html. Por isso, o rem mantém o mesmo valor em qualquer ponto da página.

O rem usa a fonte do body ou do html?

O rem usa a fonte do elemento html, que é a raiz do documento. Alterar a fonte do body não muda o valor de 1rem.

Quanto vale 1rem por padrão?

Na maioria dos navegadores, 1rem vale 16px quando a raiz não define outro tamanho. Contudo, o usuário pode alterar esse padrão nas configurações do navegador.

Por que o em fica cada vez maior em elementos aninhados?

Porque cada filho herda a fonte calculada do pai e multiplica pelo valor informado. Esse efeito acumulado se chama composição.

Devo usar px, em ou rem para fontes?

Prefira unidades relativas, como rem, para respeitar a configuração de fonte do usuário. A MDN recomenda evitar unidades absolutas no font-size por questões de acessibilidade.

Posso usar em e rem no mesmo projeto?

Sim, e essa é a abordagem mais comum. Use rem para a tipografia global e em para espaçamentos que acompanham o componente.