Entendiendo las Unidades de Viewport Dinámicas en CSS
Si alguna vez has creado un diseño a pantalla completa en móvil y has notado que el contenido se recorta detrás de la barra de direcciones del navegador, te has encontrado con el clásico problema de 100vh. La solución solía implicar trucos con JavaScript. Ahora, CSS lo maneja de forma nativa con unidades de viewport modernas: svh, lvh y dvh.
Puntos Clave
- La unidad tradicional
vhse mapea al viewport grande en móviles, causando desbordamiento de contenido cuando la barra de direcciones del navegador está visible. - CSS ahora define tres estados de viewport—grande (
lvh), pequeño (svh) y dinámico (dvh)—cada uno con su propio conjunto de unidades. - Usa
svhpara contenido above-the-fold,lvhpara diseños inmersivos a pantalla completa, ydvhpara diseños adaptativos que responden a cambios en la interfaz del navegador. - Las unidades de viewport dinámicas no tienen en cuenta los teclados virtuales; prueba los diseños con muchos campos de entrada en dispositivos reales.
- Incluye siempre un fallback de
vhpara navegadores antiguos que no soportan las unidades más nuevas.
Por Qué vh Falla en Móviles
En escritorio, vh funciona de manera confiable. En móviles, la interfaz del navegador—barra de direcciones, pestañas, controles de navegación—se expande y contrae mientras los usuarios hacen scroll. La altura del viewport cambia, pero vh no la sigue.
vh refleja el viewport grande (similar a lvh), que asume que el chrome del navegador está completamente retraído. Entonces, cuando la barra de direcciones está visible, un elemento de 100vh puede desbordar el área visible. El contenido se corta, los botones se vuelven inaccesibles y los diseños se rompen.
Los Tres Estados de Viewport: Grande, Pequeño y Dinámico
La especificación CSS Values and Units define tres estados distintos de viewport para abordar esto:
- Viewport grande — medido cuando toda la interfaz del navegador está retraída (altura máxima disponible)
- Viewport pequeño — medido cuando toda la interfaz del navegador está expandida (altura mínima disponible)
- Viewport dinámico — rastrea el estado que esté activo actualmente
Cada estado tiene un conjunto correspondiente de unidades CSS:
| Estado de Viewport | Unidad de Altura | Unidad de Ancho |
|---|---|---|
| Grande | lvh | lvw |
| Pequeño | svh | svw |
| Dinámico | dvh | dvw |
Cada familia también incluye variantes min, max, inline y block (dvi, dvb, svmin, lvmax, etc.).
Importante: vh efectivamente se mapea a lvh en navegadores modernos. Ambos reflejan el tamaño del viewport grande.
En navegadores de escritorio sin interfaz dinámica, los tres tamaños de viewport son idénticos.
Cuándo Usar svh, lvh y dvh
Usa svh cuando el contenido deba permanecer completamente visible en la carga inicial de la página, antes de cualquier desplazamiento. Garantiza que tu diseño se ajuste dentro del viewport más pequeño posible—con el chrome del navegador completamente visible.
/* Contenido siempre visible al cargar, sin necesidad de scroll */
.above-the-fold {
min-height: 100svh;
}
Usa lvh para experiencias inmersivas a pantalla completa—juegos, pantallas de inicio o shells de aplicación—donde quieres llenar el máximo espacio disponible.
/* Llena la pantalla cuando el chrome del navegador está oculto */
.fullscreen-app {
height: 100lvh;
}
Usa dvh cuando quieras que el diseño se adapte a medida que cambia la interfaz del navegador. Es la opción más práctica para la mayoría de los diseños responsive.
/* Problemático en móviles */
.hero { height: 100vh; }
/* Se adapta a cambios en el chrome del navegador */
.hero {
height: 100vh; /* Fallback para navegadores antiguos */
height: 100dvh; /* Los navegadores modernos usan esto */
}
El patrón de fallback anterior funciona porque los navegadores que no reconocen dvh ignorarán la segunda declaración y aplicarán la primera. Los navegadores modernos aplican la última declaración válida, por lo que 100dvh tiene efecto.
Discover how at OpenReplay.com.
La Advertencia del Teclado Virtual
dvh maneja el redimensionamiento de la barra de direcciones, pero no los teclados virtuales. Cuando un usuario toca un campo de entrada y aparece el teclado en pantalla, las unidades de viewport normalmente no se ajustan porque la mayoría de los navegadores redimensionan solo el viewport visual por defecto.
Para activar el comportamiento de diseño consciente del teclado, puedes usar la meta etiqueta interactive-widget:
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">
El valor resizes-content le indica al navegador que redimensione el viewport cuando se abre el teclado virtual. Otros valores incluyen resizes-visual (el predeterminado, que solo redimensiona el viewport visual) y overlays-content (el teclado se superpone sin redimensionar nada). El soporte para este comportamiento existe actualmente principalmente en navegadores basados en Chromium.
Chrome también ofrece control programático a través de la VirtualKeyboard API. El soporte cross-browser para esa API sigue siendo limitado, así que si tu diseño depende del espacio visible debajo de un input, prueba cuidadosamente en dispositivos reales.
Soporte de Navegadores
svh, lvh y dvh son soportados en:
- Chrome 108+
- Safari 15.4+
- Firefox 101+
La cobertura es sólida en navegadores modernos. El patrón de fallback height: 100vh mostrado arriba maneja entornos antiguos con elegancia. También puedes verificar la compatibilidad actual en la documentación de unidades de viewport de MDN.
Eligiendo la Unidad Correcta
- ¿El contenido debe ajustarse en la carga inicial? →
svh - ¿Diseño inmersivo a pantalla completa? →
lvh - ¿Diseño adaptativo que responde a la interfaz del navegador? →
dvh - ¿Soportando navegadores antiguos? → Incluye siempre un fallback de
vh
Conclusión
El problema de la altura del viewport móvil en CSS ahora tiene una solución limpia y nativa. Cambia vh por dvh en la mayoría de los casos, usa svh cuando la visibilidad above-the-fold importa, y reserva lvh para experiencias a pantalla completa. Siempre empareja las unidades más nuevas con un fallback de vh para compatibilidad hacia atrás, y recuerda que los teclados virtuales requieren manejo separado. No se requiere JavaScript.
Preguntas Frecuentes
Sí, pero con precaución. Debido a que dvh cambia a medida que la interfaz del navegador se expande o contrae, un elemento fijo dimensionado con dvh puede desplazarse visiblemente durante el scroll. Para encabezados o pies de página sticky con altura fija, usar valores estáticos en píxeles o rem suele ser más predecible. Reserva dvh para contenedores de altura completa en lugar de elementos pequeños de tamaño fijo.
El impacto en el rendimiento es insignificante para la mayoría de los diseños. Sin embargo, si aplicas dvh a muchos elementos profundamente anidados que desencadenan recálculos complejos de diseño, podrías ver jank menor en dispositivos de gama baja. Perfiliza en hardware real si el rendimiento es crítico.
Siguen la misma lógica pero se aplican al ancho del viewport. En la mayoría de los navegadores móviles, el ancho no cambia cuando aparece o desaparece la barra de direcciones, por lo que svw, lvw y dvw típicamente devuelven el mismo valor. La distinción importa más en dispositivos o navegadores donde paneles laterales u otros elementos de interfaz afectan el ancho disponible.
Agrega interactive-widget=resizes-content a tu meta etiqueta viewport. Esto le indica al navegador que reduzca el viewport de diseño cuando se abre el teclado, lo que significa que dvh reflejará el espacio reducido. Sin esta configuración, el teclado se superpone al contenido y las unidades de viewport permanecen sin cambios. Prueba en dispositivos reales ya que el comportamiento varía entre navegadores y plataformas.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.