CSS em e-mail: quais seletores e regras sobrevivem em cada cliente

Por Mara Levin · Atualizado em 7 de outubro de 2026 · Dados do caniemail e documentação das ferramentas lidos nesse dia

A resposta curta

Em e-mail, o CSS que importa é o que cabe no atributo style. Seletores de classe simples funcionam quase em todo lugar, mas o app do Gmail ignora o bloco <style> em contas que não são do Google, e o Outlook para Windows não entende seletores filho, irmão, universal nem @media. Por isso: escreva a leitura essencial inline, use classes simples só para melhorias (empilhar colunas, hover, modo escuro) e deixe um padrão legível para quem ignora essas regras. Os números vêm do caniemail.com, com link para a ficha ao lado de cada afirmação.

O problema por trás dos seletores

Antes de decidir entre .classe e td, vale entender por que um seletor desaparece. A ficha do elemento style lista três limites que explicam a maior parte dos casos: o Gmail não aceita style dentro do body, limita o bloco a 16 KB, e nos apps para iOS e Android não o aceita quando a conta não é do Google. A ficha do Outlook para Windows traz outro: a tag precisa ser declarada antes de as regras serem usadas.

O resultado aparece nas tabelas abaixo: a coluna do Gmail nos apps vem quase sempre marcada como "Parcial" para seletores, e a coluna do Outlook para Windows traz vários "Não". As tabelas usam as colunas mais representativas de cada grupo de clientes; as fichas ligadas têm a lista completa.

Seletores

Seletor Gmail web Gmail iOS Outlook Windows Outlook.com Apple Mail Yahoo
tipo (td) Sim Parcial Sim Sim Sim Sim
classe (.x) Sim Parcial Sim Sim Sim Sim
id (#x) Sim Parcial Sim Sim Sim Sim
descendente (a b) Sim Parcial Sim Sim Sim Sim
filho (a > b) Sim Parcial Não Sim Sim Sim
irmão adjacente (a + b) Sim Parcial Não Sim Sim Sim
universal (*) Sim Parcial Não Sim Sim Sim
atributo ([x]) Parcial Parcial Não Parcial Sim Parcial
encadeado (.a.b) Sim Parcial Com defeito Com defeito Sim Sim

Fonte: dados do caniemail.com atualizados em 16 de setembro de 2026, com a entrada mais recente de cada cliente. "Outlook Windows" são as versões de desktop até a 2019. "Com defeito" significa que o cliente aplica a regra, mas de forma errada.

Duas armadilhas que um revisor de código não vê

A primeira é o seletor encadeado. A ficha de seletor encadeado informa que, no Outlook para Windows, os estilos são aplicados ao primeiro seletor da cadeia: uma regra escrita como .botao.principal acaba valendo para todo .botao. No Outlook.com o problema é outro, já que só o primeiro seletor da cadeia recebe o prefixo, e as classes do HTML recebem todos. Prefira classes únicas com nomes distintos, como .botao-principal.

A segunda é o seletor universal. A ficha do seletor universal mostra que o * não funciona no Outlook para Windows nem no Gmail em navegador de celular, e que nos apps do Gmail ele depende da conta. Um "reset" como * { margin: 0 }, comum em modelos copiados da web, simplesmente não age onde mais faria falta; escreva a margem zero em cada td, p e título.

Pseudo-classes e pseudo-elementos

Recurso Gmail web Gmail iOS Outlook Windows Outlook.com Apple Mail Yahoo
:first-child Não Não Não Parcial Sim Sim
:nth-child() Não Não Não Não Sim Não
:not() Não Não Não Não Sim Não
:hover Sim Não Não Parcial Sim Sim
:active Não Não Não Parcial Parcial Sim
:visited Não Não Não Parcial Não Sim
::first-line Não Não Não Parcial Sim Sim

Mesma fonte e data da tabela anterior. No Outlook.com, as entradas parciais valem só para seletores de tipo, como a:hover, e não para classes.

O padrão é claro: :first-child, :nth-child() e :not() são recursos de Apple Mail, e quem os usa para alternar a cor das linhas de uma tabela vai ver o efeito em uma parte pequena da lista. Em vez de contar com o seletor, marque a linha no próprio modelo com uma classe ou, melhor, com a cor direto no style. Para o :hover, o caniemail mostra suporte no Gmail web, no Apple Mail e no Yahoo, mas não no Gmail para iOS nem no Outlook para Windows; trate o hover como um detalhe a mais, nunca como a única pista de que algo é clicável.

At-rules: @media, @font-face e o resto

At-rule Gmail web Gmail iOS Outlook Windows Outlook.com Apple Mail Yahoo
@media Parcial Parcial Não Parcial Sim Parcial
@media (hover) Não Não Não Sim Sim Não
@media (orientation) Sim Não Não Sim Sim Não
@import Não Não Sim Não Sim Não
@font-face Não Não Parcial Não Sim Não
@keyframes Não Não Não Não Sim Sim
@supports Não Não Não Não Sim Sim (reescrito)

A ficha de @media traz detalhes que decidem o desenho do e-mail: o Gmail não aceita consultas baseadas em altura; o Yahoo aceita só screen, min-width, max-width e as equivalentes de altura; o Outlook.com remove media queries aninhadas; o Outlook para Windows não aceita nenhuma; e, no app do Gmail, vale de novo a limitação das contas que não são do Google. Em resumo, não dá para depender da media query para tornar o layout legível em tela pequena.

A saída é fazer o contrário: o layout estreito é o padrão, e a media query só o enriquece. A tabela externa tem width:100% com max-width:600px, o que funciona porque o max-width, segundo a ficha própria, é aceito no Outlook para Windows em tabelas. Para o Outlook ainda respeitar a largura quando o contêiner for um div, a técnica clássica é a tabela-fantasma dentro de um comentário condicional, que só o Outlook lê:

<!--[if mso]>
<table role="presentation" width="600" align="center" cellspacing="0" cellpadding="0" border="0"><tr><td>
<![endif]-->
<div style="max-width:600px; margin:0 auto;">
  <!-- conteúdo da mensagem -->
</div>
<!--[if mso]>
</td></tr></table>
<![endif]-->

O comentário condicional [if mso] é um recurso do Outlook para Windows; os demais clientes tratam tudo isso como comentário HTML e ignoram. Se o seu layout já é todo em tabelas, como no exemplo abaixo, nem precisa dele.

Um exemplo completo, em português

O modelo a seguir junta as decisões acima. Duas colunas de 300 px empilham quando a tela é estreita, mas só se o cliente ler a media query; se não ler, ficam lado a lado dentro de uma tabela de 100% de largura, o que ainda é legível. O botão tem hover como melhoria, e a cor do botão e o texto estão inline.

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    /* Só melhorias: se o cliente ignorar este bloco, o e-mail continua legível */
    @media screen and (max-width: 600px) {
      .coluna { display: block !important; width: 100% !important; }
    }
    a.botao:hover { background-color: #0848a3 !important; }
  </style>
</head>
<body>
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
      <td align="center">
        <table role="presentation" width="600" style="width:100%; max-width:600px;" cellspacing="0" cellpadding="0" border="0">
          <tr>
            <td class="coluna" width="300" style="width:300px; padding:16px; font-family:Arial, Helvetica, sans-serif; font-size:16px; line-height:24px; color:#333333;">
              Sua fatura de outubro está disponível.
            </td>
            <td class="coluna" width="300" style="width:300px; padding:16px;">
              <a class="botao" href="https://exemplo.com.br/faturas/4812"
                 style="display:inline-block; padding:12px 24px; background-color:#0a58ca; color:#ffffff; font-family:Arial, Helvetica, sans-serif; font-size:16px; text-decoration:none;">Ver fatura</a>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>

Repare na ordem dos blocos e no !important das regras da media query: sem ele, a largura inline de 300 px vence a regra do bloco style e as colunas nunca empilham. Se você usa Outlook para Windows como referência, confira também o mso-line-height-rule:exactly, que a ficha de line-height recomenda porque unidades em e px se comportam de forma estranha ali.

Deixando uma ferramenta fazer o inline

Escrever o CSS à mão em cada td é cansativo, e o fluxo comum é escrever classes e deixar a ferramenta copiá-las para o atributo style. Quatro opções documentadas:

  • Juice. Dado um HTML, o Juice copia as propriedades CSS para o atributo style. O README descreve a opção addImportantToPseudoClasses, justamente porque regras com pseudo-classes como :hover não podem ser inlined.
  • MJML. Em mj-style, o atributo inline="inline" inlina as regras; sem ele, o CSS vai para o head. Com mj-attributes e mj-class você define padrões e grupos de atributos, conforme a documentação.
  • Maizzle. O inline vem ligado por padrão; a página do transformador explica que ele continua importante principalmente por causa do Gmail e do Outlook no Windows, e que uma tag style com o atributo embed é ignorada.
  • React Email. O componente Tailwind converte as classes, e a documentação manda usar o pixelBasedPreset porque o rem do Tailwind não é aceito por alguns clientes. A página Tailwind traz o exemplo.
import juice from 'juice';

const html = juice(fonteHtml); // copia as regras do <style> para o atributo style de cada elemento
<mj-head>
  <mj-attributes>
    <mj-class name="aviso" color="#5b6470" font-size="14px" />
  </mj-attributes>
  <mj-style inline="inline">
    .rodape a { color: #0a58ca; }
  </mj-style>
</mj-head>

Nenhuma dessas documentações promete renderização idêntica em todos os clientes, e é por isso que o passo final continua manual. Para escolher entre os dois frameworks de código, veja MJML contra React Email; para a ponte entre CSS e acessibilidade, o guia de acessibilidade em e-mail HTML.

Como depurar quando o e-mail não sai como o esperado

  1. Identifique o grupo do cliente. Outlook para Windows, app do Gmail com conta que não é do Google e "os demais" quebram por motivos diferentes. Descobrir o grupo elimina metade das hipóteses.
  2. Abra o HTML recebido. Veja o código-fonte da mensagem entregue e procure sua regra: se ela foi removida, reescrita com prefixo ou movida, o cliente a processou antes de você.
  3. Reduza. Tire as regras uma a uma até o defeito sumir, depois traga a regra de volta em versão inline.
  4. Registre. Anote o cliente, a regra e a data. O caniemail mostra a data do último teste de cada recurso, e uma ficha antiga é um bom motivo para reconfirmar.

Para os efeitos que dependem de cor em modo escuro, leia o guia de modo escuro; para o panorama de motores de renderização, o guia de compatibilidade entre clientes.

Perguntas frequentes

Por que minhas classes CSS não funcionam no app do Gmail?

Quase sempre por causa do tipo de conta. Nas fichas de seletor de classe, de elemento style e de @media, o caniemail marca o app do Gmail (iOS e Android) como parcial e explica que não há suporte quando a conta não é do Google, por exemplo um endereço Outlook ou Yahoo lido no app do Gmail. Nesses casos só o CSS escrito no atributo style de cada elemento chega ao leitor, por isso tudo o que sustenta a leitura precisa ficar inline.

Dá para usar :hover em botões?

Como detalhe, sim; como regra de usabilidade, não. A ficha do :hover mostra suporte no Gmail web, no Apple Mail e no Yahoo, suporte só em seletores de tipo no Outlook.com, e nenhum no Gmail para iOS nem no Outlook para Windows. Além disso, a documentação do Juice avisa que regras com pseudo-classe como :hover não podem ser inlined, e oferece a opção addImportantToPseudoClasses para que o estilo inline não as sobrescreva.

Preciso escrever !important nas media queries?

Sim, porque o estilo inline tem prioridade sobre o bloco style, e a media query só consegue vencer com !important. Escreva a palavra-chave em minúsculas e com um espaço antes, como em "width: 100% !important": o caniemail registra que o Gmail só aceita em minúsculas, que o Outlook para Windows só aceita com espaço antes e que o Yahoo descarta a declaração quando falta o espaço numa regra com imagem de fundo.

Qual ferramenta faz o inline por mim?

Todas as que a documentação cita fazem, cada uma à sua maneira. O MJML inlina o que estiver em mj-style com inline="inline"; o Maizzle inlina por padrão e justifica isso pelos limites do Gmail e do Outlook no Windows; o Juice é o motor que o Maizzle expõe; e o React Email converte as classes do componente Tailwind. Escolha pela linguagem em que seu time já escreve e confira o HTML final nos clientes da sua lista.