Programação Por Equipe DevBras

Capa do artigo: iPhone dá zoom ao tocar no campo: a regra dos 16 pixels e a gambiarra a evitar

iPhone dá zoom ao tocar no campo: a regra dos 16 pixels e a gambiarra a evitar

Entenda por que o Safari do iPhone amplia a página quando o campo tem letra menor que 16 pixels, corrija no CSS sem bloquear o zoom e encontre os campos culpados com um script.

Na página de checkout, a pessoa toca no campo "CEP" e a tela inteira aproxima sozinha. O botão "Calcular frete" sai para fora da área visível, o texto fica cortado nas laterais e ela precisa fazer o gesto de pinça para voltar. Ninguém pediu esse zoom. No Android, o mesmo formulário não faz isso.

A resposta curta: o Safari do iPhone amplia a página ao focar um campo cujo texto tem menos de 16 pixels. A correção é deixar input, select e textarea com font-size de pelo menos 16 pixels. Não resolva com maximum-scale=1 ou user-scalable=no no viewport: isso tira o zoom de quem precisa dele.

Por que o iPhone faz isso

É um comportamento de acessibilidade do navegador. Se o texto do campo é pequeno demais para ler confortavelmente enquanto se digita, o Safari amplia a área do campo para a pessoa enxergar o que escreve. A intenção é boa. O efeito colateral é que a página fica ampliada depois que o foco sai, e o layout que você desenhou para caber na tela deixa de caber.

Na prática, a maioria dos navegadores no iPhone usa o mesmo motor do Safari, então o Chrome no iPhone costuma se comportar igual. No Android, os navegadores em geral não fazem esse zoom automático, e por isso o problema passa despercebido por quem testa só lá ou no desktop.

De onde vem a letra pequena

Quase nunca alguém escreve "14px no input" de propósito. O tamanho pequeno chega por caminhos indiretos:

  • Controles de formulário não herdam a fonte do corpo por padrão. O navegador aplica um estilo próprio a eles, geralmente menor que 16 pixels. Se o seu CSS não define a fonte do campo, ela fica no padrão do navegador.
  • Raiz reduzida. O projeto define html { font-size: 87.5%; } para ter 14 pixels como base, e o campo com font-size: 1rem herda os 14.
  • Componente de biblioteca. O framework de interface usa um tamanho "compacto" de 14 pixels nos campos.
  • Media query para telas pequenas que reduz a fonte "para caber mais", justamente no celular.

Como corrigir sem tirar o zoom de ninguém

  1. Descubra quais campos estão abaixo de 16 pixels (script mais abaixo).
  2. Defina no CSS global um tamanho mínimo para todos os controles de texto.
  3. Faça os controles herdarem a família da fonte do site, para o campo não destoar.
  4. Revise componentes de bibliotecas que sobrescrevem o tamanho.
  5. Confira o meta viewport e remova qualquer bloqueio de zoom.
  6. Teste num iPhone de verdade, ou no simulador de iOS do Xcode, que roda o Safari móvel.
input,
select,
textarea {
  font-family: inherit;
  font-size: max(16px, 1rem);
}

O max() garante os 16 pixels mesmo que a raiz do site seja menor, e respeita uma raiz maior se a pessoa aumentou o tamanho de fonte no sistema ou no navegador. Ele é suportado pelos navegadores atuais. Se você usa uma biblioteca de componentes, aplique a regra com especificidade suficiente para vencer o estilo dela, ou use a variável de tema que a biblioteca oferece para isso.

O meta viewport correto continua sendo o simples:

<meta name="viewport" content="width=device-width, initial-scale=1">

A gambiarra que você vai encontrar na internet

A solução mais copiada é acrescentar maximum-scale=1 (às vezes junto de user-scalable=no) ao meta viewport. Ela some com o zoom no foco, mas o preço é alto: em vários navegadores, principalmente no Android, a pessoa perde também o zoom de pinça. Quem tem baixa visão e amplia a tela para ler o valor do frete fica sem essa saída.

As diretrizes WCAG têm um critério específico sobre redimensionar texto, e bloquear o zoom é uma das falhas mais comuns apontadas em auditoria. Mesmo que o Safari moderno ignore parte dessas instruções para preservar a acessibilidade, você não controla todos os navegadores que vão abrir o seu site. Corrigir a fonte resolve a causa, e o bloqueio só esconde o sintoma.

Outra gambiarra é deixar o campo com 16 pixels e aplicar transform: scale() para ele parecer menor. Funciona visualmente, mas complica alinhamento, área de toque e cálculo de posição do cursor. Se o design insiste em letra pequena no campo, vale a conversa: 16 pixels é um tamanho de leitura confortável no celular, e o campo é justamente onde a pessoa precisa ler com atenção.

Como achar os campos culpados

Cole no console, em cada página com formulário. Rode com a largura de celular no modo responsivo, porque media queries podem mudar o tamanho:

[...document.querySelectorAll('input, select, textarea')]
  .filter((el) => el.type !== 'hidden')
  .map((el) => ({ el, tamanho: parseFloat(getComputedStyle(el).fontSize) }))
  .filter(({ tamanho }) => tamanho < 16)
  .forEach(({ el, tamanho }) => console.log(tamanho + 'px', el.name || el.id, el));

No checkout do exemplo, o resultado apontou "cep", "numero" e "complemento" com 14 pixels, vindos de uma classe campo-compacto criada para alinhar os três na mesma linha. A correção foi subir para 16 pixels e deixar o "complemento" ir para a linha de baixo no celular.

O modo responsivo do desktop serve para achar os campos, mas não reproduz o zoom. A confirmação final precisa de um iPhone ou do simulador. Se você tem um Mac, o Safari permite inspecionar a página aberta no aparelho conectado, o que ajuda a ver o tamanho calculado ali mesmo.

Junto com o zoom, confira o teclado

Quando o campo está na metade de baixo da tela, o zoom costuma vir acompanhado de outro problema: o teclado virtual cobre o botão de enviar. As duas coisas aparecem no mesmo teste, e a segunda está em teclado virtual que cobre o botão. Aproveite também para conferir se cada campo abre o teclado certo, numérico para CEP e com arroba para e-mail, como explica inputs HTML5 que ajudam.

E se você está montando o CSS do zero, comece pelo celular: CSS mobile-first mostra como definir a base para a tela pequena, onde 16 pixels nos campos é o ponto de partida natural.

Erros comuns

  • Bloquear o zoom no meta viewport. O pulo some, e junto vai o zoom de pinça de quem precisa ampliar para ler.
  • Corrigir só o input. select e textarea também disparam o zoom, e o campo de estado no endereço continua pulando.
  • Confiar no modo responsivo do desktop. Ele não reproduz o comportamento do Safari móvel e o problema chega ao cliente.
  • Reduzir a fonte numa media query para celular. A tela que mais precisa de letra legível fica com a menor.
  • Esquecer componentes de terceiros. O seletor de data ou o campo de busca da biblioteca mantém 14 pixels e continua ampliando a página.
  • Usar transform: scale() para disfarçar. O campo parece menor, mas o alinhamento e a área de toque ficam imprevisíveis.

Checklist

  • Todos os input, select e textarea visíveis têm pelo menos 16 pixels de fonte.
  • A regra global usa max(16px, 1rem) ou equivalente.
  • O meta viewport não tem maximum-scale nem user-scalable=no.
  • Componentes de bibliotecas foram conferidos com o script.
  • Nenhuma media query reduz a fonte dos campos no celular.
  • O formulário foi testado num iPhone real ou no simulador.

Pegue um iPhone, abra o formulário mais importante do seu sistema e toque no último campo. A página ficou do mesmo tamanho ou você precisou fazer pinça para enxergar o botão de novo?

Avalie este artigo

Referência: https://developer.mozilla.org/docs/Web/HTML/Element/input