Na web aberta, env(safe-area-inset-*) mantém seus botões livres do notch, da Dynamic Island e do indicador de início do iPhone. Dentro de um WebView, essas mesmas variáveis podem resolver para zero, a primeira pintura pode ignorá-las, e a barra de ação inferior —o botão de ordem, a confirmação de trade, conectar wallet— desliza para baixo da barra de gestos de início, onde os toques nunca são registrados. Para um app de trading, isso significa que o controle que o usuário mais precisa é o que ele não consegue alcançar. Um runtime de propriedade do host expõe as margens de safe area nativas para que todos os motores respeitem o hardware.

O modo edge-to-edge é a armadilha padrão

O iOS expõe as safe areas como CSS env(safe-area-inset-top/right/bottom/left). Elas só carregam um valor real quando a página opta por viewport-fit=cover —exatamente o que a maioria das shells de app de tela cheia faz para parecer nativa. Ao optar, o navegador desenha o conteúdo de ponta a ponta, debaixo da Dynamic Island e do indicador de início. Se você esquece de preencher seu chrome fixo com env(), o cabeçalho se esconde atrás da "pílula" e a barra inferior desliza sob a barra de início. No Android, o Chrome lida com notch de forma diferente e a variável resolve para zero em muitos dispositivos, então o mesmo CSS que parece bom em um telefone está quebrado em outro.

O WKWebView quebra a primeira pintura

O bug 191872 da WebKit piora as coisas: os valores de env(safe-area-inset-*) podem não ser definidos até um momento depois de carregar a página em um WKWebView. Se seu layout inicial depende deles, os usuários veem um lampejo de layout incorreto —o CTA sob o indicador de início— antes da WebKit alcançar. Uma solução comum é adicionar um fallback com max() como padding-bottom: max(12px, env(safe-area-inset-bottom)) e re-disparar o layout após o carregamento. Após uma rotação (retrato → paisagem → retrato) os valores também podem ficar presos em zero até o próximo passe de layout, então uma página que estava certa fica errada.

O que quebra quando a UI é ocluída

  • O botão de ordem/trade fica inalcançável. A ação principal fica sob o indicador de início, onde os toques são engolidos pelo gesto do sistema.
  • Conectar wallet e confirmar desaparecem. O botão que completa um fluxo é o que a barra de hardware esconde.
  • Cabeçalhos e status somem atrás da Island. Títulos, saldos e controles de nav deslizam atrás do notch.
  • As telas de trading em landscape quebram pior. O notch gira para o lado e as margens mudam, mas o WebView pode não recalcular —deixando controles laterais cortados.

A solução do runtime

Um runtime de propriedade do host lê as margens de safe area nativas da plataforma e as entrega à página como um conjunto confiável de valores —via API de ponte ou variáveis CSS injetadas— para que env() sempre resolva bem na primeira pintura e após rotacionar. O host mantém a barra de ação inferior acima do indicador de início, o cabeçalho livre da Island e o layout estável entre orientações. Uma integração, todos os motores, uma UI que o usuário realmente pode tocar.

DimensãoWebViewRuntime de propriedade do host
Origem da margemCSS env() (pode ser 0)Margens nativas da plataforma
Primeira pinturaBug 191872: margens vaziasConfiável desde a primeira pintura
RotaçãoPreso em 0Recalculado
CTA inferiorSob a barra de inícioLivre da barra de início
CabeçalhoSob a IslandLivre da Island
ConsistênciaPor motorUniforme

Um app nativo fixa seu chrome acima do indicador de início em cada telefone. Um WebView puro deixa o botão mais importante onde os toques morrem. Um runtime dá à página margens reais — e uma UI que o usuário alcança.

Fontes