En la web abierta, env(safe-area-inset-*) mantiene tus botones libres del notch, la Dynamic Island y el indicador de inicio del iPhone. Dentro de un WebView esas mismas variables pueden resolverse a cero, el primer render puede ignorarlas, y la barra de acción inferior —el botón de orden, la confirmación de operación, conectar wallet— resbala bajo la barra de gestos del inicio, donde los toques nunca se registran. Para una app de trading, eso significa que el control que más necesita el usuario es el que no puede alcanzar. Un runtime propiedad del host expone los márgenes de zona segura nativos para que todos los motores respeten el hardware.
El modo edge-to-edge es la trampa por defecto
iOS expone las zonas seguras como CSS env(safe-area-inset-top/right/bottom/left). Solo llevan un valor real cuando la página opta por viewport-fit=cover —que es exactamente lo que hacen la mayoría de las shells de app de pantalla completa para verse nativas. Al optar, el navegador dibuja el contenido de borde a borde, debajo de la Dynamic Island y del indicador de inicio. Si olvidas rellenar tu chrome fijo con env(), el encabezado se oculta tras la "pastilla" y la barra inferior resbala bajo la barra de inicio. En Android, Chrome maneja los notch de forma distinta y la variable resuelve a cero en muchos dispositivos, así que el mismo CSS que se ve bien en un teléfono está roto en otro.
WKWebView rompe el primer render
El bug 191872 de WebKit empeora las cosas: los valores de env(safe-area-inset-*) pueden no estar definidos hasta un momento después de cargar la página en un WKWebView. Si tu diseño inicial depende de ellos, los usuarios ven un destello de diseño incorrecto —el CTA bajo el indicador de inicio— antes de que WebKit se ponga al día. Una solución común es añadir un respaldo con max() como padding-bottom: max(12px, env(safe-area-inset-bottom)) y re-disparar el layout tras la carga. Tras una rotación (retrato → paisaje → retrato) los valores también pueden quedarse en cero hasta el siguiente pase de layout, así que una página que estaba bien se vuelve incorrecta.
Qué se rompe cuando la UI está ocluida
- El botón de orden/operación es inalcanzable. La acción principal queda bajo el indicador de inicio, donde los toques los traga el gesto del sistema.
- Conectar wallet y confirmar desaparecen. El botón que completa un flujo es el que oculta la barra de hardware.
- Encabezados y estado desaparecen tras la Island. Títulos, saldos y controles de nav resbalan tras el notch.
- Las vistas de trading en landscape se rompen peor. El notch rota al lado y los márgenes cambian, pero el WebView puede no recalcular —dejando controles laterales recortados.
La solución del runtime
Un runtime propiedad del host lee los márgenes de zona segura nativos de la plataforma y los entrega a la página como un conjunto confiable de valores —mediante una API de puente o variables CSS inyectadas— para que env() siempre resuelva bien en el primer render y tras rotar. El host mantiene la barra de acción inferior por encima del indicador de inicio, el encabezado libre de la Island y el diseño estable entre orientaciones. Una integración, todos los motores, una UI que el usuario realmente puede tocar.
| Dimensión | WebView | Runtime propiedad del host |
|---|---|---|
| Origen del margen | CSS env() (puede ser 0) | Márgenes nativos de la plataforma |
| Primer render | Bug 191872: márgenes vacíos | Confiable desde el primer render |
| Rotación | Quedan en 0 | Recalculados |
| CTA inferior | Bajo la barra de inicio | Libre de la barra de inicio |
| Encabezado | Bajo la Island | Libre de la Island |
| Consistencia | Por motor | Uniforme |
Una app nativa fija su chrome sobre el indicador de inicio en cada teléfono. Un WebView puro deja el botón más importante donde los toques mueren. Un runtime le da a la página márgenes reales — y una UI que el usuario puede alcanzar.
Fuentes
- WebKit Bug 191872 — env(safe-area-inset-*) no se define en el primer render — en WKWebView los márgenes pueden ser cero hasta poco después de cargar, causando un destello de diseño incorrecto.
- Apple Developer — Zonas seguras de interfaz humana — mantén el contenido libre de notch, Dynamic Island e indicador de inicio usando márgenes de zona segura.
- meta viewport — viewport-fit=cover y márgenes de zona segura —
viewport-fit=coverdibuja contenido en el área del notch/Dynamic Island y requiere rellenoenv()para mantenerlo libre. - WKWebView Gotchas — márgenes de zona segura, teclado y rotación — bug 191872 de WebKit y bugs de rotación donde los márgenes se quedan en 0.
- Saabbir Hossain — Márgenes de Zona Segura (Notch y Home Bar) — la solución
env()y soporte de navegadores parasafe-area-inset-*en iOS 11+.