A tipografia do WebView não é governada pelos padrões web e sim pelo SO subjacente. O iOS desenha com San Francisco e PingFang SC, que suportam a faixa completa 100–900; o Android desenha com Roboto e Noto, onde builds antigos expõem apenas 400/500/700 e o 500 é silenciosamente rebaixado para 400. O fallback de fonte diverge — Noto Color Emoji no Android versus Apple Color Emoji no iOS — e kernels de fabricante como o Tencent X5 desativam totalmente o fallback de fontes fora da lista branca. O zoom de texto do sistema anula o CSS: WebSettings.setTextZoom no Android e UIContentSizeCategory no iOS multiplicam silenciosamente cada px, rem e em, quebrando layouts. O resultado é uma tipografia de marca que fica certa em um motor e quebrada no seguinte — emojis tofu, pesos colapsados e estouro de layout. Um runtime próprio do host trava a tipografia: uma pilha de fontes controlada, zoom de sistema limitado, fontes de fallback garantidas e mapeamento de pesos consistente dos quais a página não pode se desviar.
Uma lista de fontes, dois desenhos diferentes
A mesma declaração font-family resolve glifos, hinting e mapas de peso diferentes em cada plataforma. O PingFang SC no iOS carrega a faixa completa 100–900, enquanto o Roboto do sistema no Android — especialmente em builds antigos — traz apenas 400, 500 e 700, e o 500 costuma ser ignorado ou rebaixado para 400. Um font-weight: 500 que no iOS parece um médio limpo, no Android renderiza como um 400 comum, ou como um fallback tracejado que parece mais pesado do que o previsto. Colocar -apple-system, Roboto, "PingFang SC" não reconcilia os dois; o motor apenas escolhe o primeiro nome que realmente consegue desenhar e ignora o resto.
O fallback quebra onde mais importa
O CJK e os emojis são onde as cadeias de fallback se rompem. O WebView do Android baseado em Chromium ainda traz o Droid Sans Fallback por padrão em muitos dispositivos, que não cobre as regiões de extensão Unicode — emojis novos, caracteres raros de extensão CJK — então são renderizados como caixas tofu ou pontos de interrogação. O iOS se sai melhor em Unicode recente, mas ainda cai para uma fonte não suportada se a página nunca declarar UTF-8 nem uma família de fallback. Kernels de fabricante pioram: o Tencent X5 pode desativar totalmente o fallback de fontes fora da lista branca, então mesmo as fontes web que você carrega podem não ser aplicadas. A fonte cuidadosamente escolhida da marca só é tão boa quanto o que o dispositivo por acaso instalou.
O zoom do sistema anula seu CSS silenciosamente
Este é o assassino silencioso. No Android, as configurações do sistema injetam um fator de escala global que WebSettings.setTextZoom reflete, e o WebView multiplica px, rem e em por ele antes do layout. No iOS, o UIContentSizeCategory empurra a fonte dinâmica para a página. A substituição é obrigatória: um contêiner de altura fixa com texto ampliado estoura e trunca, um layout preciso de Flex ou Grid se comprime à medida que os tamanhos de fonte incham, e os pontos de quebra responsivos quebram porque a página é forçada a uma lógica de estilo de desktop. A página nunca pediu e não consegue recusar apenas com CSS.
A solução em runtime
Um runtime próprio do host torna a tipografia determinística entre motores. Ele injeta uma pilha de fontes controlada para que cada plataforma veja apenas as famílias que realmente consegue desenhar, embute fontes de fallback garantidas — Noto Sans CJK mais Noto Color Emoji — para que emojis e glifos raros nunca se tornem tofu, normaliza -webkit-font-smoothing para antialiasing consistente, e impõe um único mapa de pesos para que 500 signifique 500 em todos os lugares. Ele limita o zoom de texto do sistema a um valor seguro e pré-carrega as fontes da marca. A página renderiza igual porque quem decide o tipo é o runtime, não o dispositivo.
| Dimensão | WebView | Runtime próprio do host |
|---|---|---|
| Mapeamento de pesos | iOS completo 100–900; Android 400/500/700, 500 rebaixado | Único mapa de pesos forçado |
| Fallback de fontes | Divergente; X5 desativa fora da lista branca | Noto CJK + Color Emoji garantidos |
| Emoji / glifos raros | Caixas tofu em muitos Android | Sempre desenhados, nunca faltam |
| Zoom do sistema | Substituição obrigatória, quebra layout | Limitado a valor seguro |
| Antialiasing | Inconsistente por motor | Normalizado entre plataformas |
| Consistência de marca | Sorte por dispositivo | Mesmo render em todos os lugares |
A série volta sempre a um fato: um WebView herda as superfícies mais fracas da plataforma e adiciona uma com formato de web. A tipografia é a superfície que o usuário vê primeiro e julga mais rápido — e em um WebView padrão é a que o dispositivo, não o designer, controla. Um runtime devolve à marca o controle de seu próprio tipo.
Fontes
- PHP.cn — Diferenças de render de fontes móveis: -apple-system do iOS vs Roboto do Android diferem em glifo, hinting e mapa de pesos; font-weight 500 ineficaz no WebView Android; X5 desativa fallback fora da lista branca — a divergência por motor na resolução de pesos e fallbacks.
- TrueSight — Tipografia defensiva em WebView: textZoom do Android e UIContentSizeCategory do iOS anulam CSS obrigatoriamente; setTextZoom(100) para travar — como o zoom do sistema quebra layouts e o bloqueio.
- CSDN Q&A — Emoji / CJK raro renderiza como tofu no WebView; fallback de fonte ausente e HarfBuzz / Color Emoji em Android antigo — por que os glifos desaparecem e como injetar Noto.
- ByteDance — Princípios de render do WebView: diferenças de pipeline WebKit (iOS) vs Blink (Android), inclusive inconsistência de font-smoothing — a divisão no nível do motor por trás da deriva de render.
- Web.dev — Web no Android: WebView é parte do pipeline de render do SO e carece dos controles de consistência do navegador — a razão estrutural pela qual a tipografia depende do dispositivo.