Cuando 100vh Miente: Solucionando Problemas de Viewport en Móviles
Construyes una sección hero de altura completa. Se ve perfecta en Chrome DevTools. La abres en tu teléfono y el contenido inferior está cortado — el botón CTA en el que invertiste tiempo posicionándolo está oculto detrás de la barra de direcciones del navegador. ¿Te suena familiar?
Esto ya no es solo una peculiaridad de Safari. Es una consecuencia de cómo se definen fundamentalmente las unidades de viewport, y también afecta a Chrome, Firefox y Samsung Internet en móviles.
Puntos Clave
100vhen móviles se calcula contra el viewport grande (barras de herramientas retraídas), que es más alto que lo que los usuarios realmente ven en la carga inicial.- Usa
100svhpara diseños estables de altura completa que se ajusten a la pantalla visible cuando las barras de herramientas están mostrándose. - Reserva
100dvhpara casos donde explícitamente quieras que el diseño se redimensione conforme cambia la UI del navegador, y acepta el costo de reflujo. - Combina unidades de viewport con
env(safe-area-inset-bottom)en pantallas edge-to-edge para evitar que el contenido quede detrás de la UI del sistema.
Por Qué 100vh Miente en Móviles
La causa raíz se reduce a dos conceptos diferentes de viewport:
- Layout viewport: lo que el navegador usa para calcular longitudes CSS, incluyendo
vh - Visual viewport: lo que el usuario realmente ve en pantalla
Los navegadores móviles intencionalmente mantienen el layout viewport fijo incluso cuando la barra de direcciones y la barra de navegación se retraen al hacer scroll. Esto significa que 100vh se calcula contra el estado de barra de herramientas expandida — el viewport grande — y ese valor es mayor que la pantalla visible cuando la página carga inicialmente.
Esto no es un bug. La especificación CSS define
vhcomo equivalente alvh(large viewport height). El navegador se está comportando correctamente. Tu diseño simplemente no lo tiene en cuenta.
Por eso la emulación móvil de DevTools se ve bien: no simula la UI dinámica del navegador. La barra de direcciones nunca se retrae en un simulador.
El Impacto en el Mundo Real
- Las secciones hero se desbordan por 56–80px en la carga inicial
- Los footers fijos quedan oscurecidos por la barra de navegación
- Los modales de pantalla completa recortan contenido en la parte inferior
- Los diseños saltan cuando las barras de herramientas se retraen a mitad del scroll (si estás usando
dvh)
Discover how at OpenReplay.com.
Soluciones Modernas: svh, dvh y lvh
CSS ahora te proporciona tres unidades explícitas de altura de viewport que corresponden a diferentes estados de las barras de herramientas:
| Unidad | Representa | Mejor Para |
|---|---|---|
lvh | Viewport grande (barras retraídas) | Mismo comportamiento que vh actual |
svh | Viewport pequeño (barras visibles) | Diseños estables, contenido siempre visible |
dvh | Viewport dinámico (estado actual) | Diseños adaptables, pero causa reflujo |
Para la Mayoría de Secciones de Altura Completa: Usa svh
.hero {
height: 100vh; /* Fallback para navegadores antiguos */
height: 100svh; /* Se ajusta dentro de la pantalla visible en la carga */
}
100svh dimensiona el elemento al viewport más pequeño posible — lo que significa que se ajusta incluso cuando las barras de herramientas están completamente visibles. Sin desbordamiento, sin recortes.
Cuando Quieras Ajuste Dinámico: Usa dvh con Cuidado
.full-height {
height: 100vh; /* Fallback */
height: 100dvh; /* Se redimensiona conforme las barras se retraen */
}
Advertencia: dvh recalcula conforme la UI del navegador cambia durante el scroll. Esto puede causar cambios visibles de diseño y repintados. No es la opción predeterminada correcta para la mayoría de secciones hero o modales — úsala solo cuando explícitamente quieras que el elemento se redimensione con el estado de las barras de herramientas.
Compatibilidad con Navegadores
svh, dvh y lvh están soportadas en Chrome 108+, Safari 15.4+ y Firefox 101+. En conjunto, esto cubre más del 90% de usuarios globalmente. Para navegadores antiguos, el fallback de 100vh maneja el resto.
Casos Especiales que Vale la Pena Conocer
Inserciones de área segura: En pantallas edge-to-edge (notch/Dynamic Island de iPhone), combina unidades de viewport con env(safe-area-inset-bottom) para evitar que el contenido quede detrás de la UI del sistema:
.hero {
height: 100svh;
padding-bottom: env(safe-area-inset-bottom);
}
Teclado en pantalla: El teclado virtual afecta principalmente al visual viewport, y su interacción con el dimensionamiento del layout viewport puede variar entre navegadores y WebViews. Esto es independiente de las unidades de viewport impulsadas por barras de herramientas y puede requerir manejo con JavaScript o la API VirtualKeyboard como mejora progresiva.
WebViews y navegadores embebidos: Los navegadores dentro de aplicaciones (Instagram, LinkedIn) a menudo tienen comportamiento de viewport no estándar. Prueba en dispositivos reales, no solo en navegadores del sistema.
Conclusión
Deja de recurrir a 100vh como tu opción predeterminada para diseños móviles de altura completa. Usa 100svh para secciones estables que necesiten ajustarse a la pantalla visible en la carga. Reserva 100dvh para casos donde el redimensionamiento dinámico sea intencional. La nueva familia de unidades de viewport existe precisamente porque el comportamiento antiguo siempre fue un compromiso — ahora tienes las herramientas para ser explícito sobre lo que realmente quieres.
Preguntas Frecuentes
No en todas partes. 100svh te da la altura de viewport más pequeña, que es más corta que 100vh. Para elementos que deberían llenar la pantalla solo después de que las barras de herramientas se retraigan, 100lvh o 100dvh pueden ser más apropiadas. Usa 100svh específicamente para contenido que debe ser completamente visible en la carga inicial de la página con las barras de herramientas mostrándose.
Puede hacerlo. Debido a que dvh recalcula cada vez que la barra de herramientas del navegador se retrae o expande durante el scroll, desencadena recálculos de diseño y repintados. Para secciones hero estáticas o modales, esta sobrecarga es innecesaria. Reserva dvh para elementos donde intencionalmente quieras que la altura rastree el viewport visible actual en tiempo real.
El comportamiento varía. En iframes estándar, las unidades de viewport hacen referencia al viewport propio del iframe, no a la página padre. En WebViews usados por navegadores dentro de aplicaciones como Instagram o Facebook, el comportamiento de las barras de herramientas no es estándar y los cálculos de unidades de viewport pueden ser impredecibles. Siempre prueba en dispositivos reales en los contextos embebidos específicos que tus usuarios encuentran.
Las unidades svh, dvh y lvh no se ven afectadas por el teclado virtual. El teclado reduce el visual viewport pero no el layout viewport al que estas unidades hacen referencia. Para manejar cambios de diseño relacionados con el teclado, investiga la API VirtualKeyboard, que te da control programático sobre cómo tu diseño responde a los cambios de visibilidad del teclado.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..