Viewport Units en CSS: ¿Por qué existen y cómo usarlas? - Parte 2
septiembre 21, 2024 - 15 minutos de lectura
Este artículo consta de dos partes. La primera incluye el contexto y la teoría, mientras que la segunda cubre la práctica. Si aún no has visto la teoría y quieres hacerlo, puedes leer la primera parte.
Para entender las medidas descritas a continuación es necesario comprender dos conceptos:
- Viewport pequeño: Se presenta cuando los controles del navegador (barra de direcciones, flechas de navegación, etc.) son visibles y ocupan el tamaño máximo que pueden tomar. En este caso el espacio disponible para la página es el mínimo posible. Normalmente se presenta apenas cargas una página, o cuando haces scroll hasta el inicio.
- Viewport grande: Cuando los controles de un navegador están en su tamaño mínimo (completamente ocultos o en un modo compacto dependiendo del navegador), el espacio disponible para la visualización de la página aumenta al máximo. En este caso hablamos de un viewport grande (large viewport). Esto normalmente ocurre cuando hacemos scroll hacia abajo en una página, pero puede variar según el navegador.
Para explicar las medidas usaremos el mismo ejemplo de la primera parte: Un teléfono móvil de 320px
de altura que al cargar el navegador tiene una barra de direcciones de 30px
, seguido por 290px
para el contenido. Cuando hago scroll la barra se oculta por completo, dejando los 320px
disponibles para la página. En este caso el viewport pequeño tendrá una altura 290px
y el viewport grande 320px
.
Una claridad antes de empezar: Me centraré siempre en las medidas relativas al height, pero para el width aplica la misma idea.
lvh
y lvw
: large viewport height y large viewport width
La unidad lvh
es el porcentaje sobre la altura del viewport grande. En el ejemplo, 100lvh = 320px
, por lo que 1lvh = 3.2px
. Si definimos un contenedor de 100lvh
de altura se verá perfectamente ajustado al 100% de la pantalla cuando los controles estén ocultos o compactos. Sin embargo cuando el navegador tenga sus controles visibles, un contenedor de 100lvh
no será totalmente visible en pantalla y tendrá un pequeño scroll.
Es particularmente útil cuando quieres que tu contenedor siempre ocupe por lo menos el 100% de la pantalla y un poco de scroll cuando los controles del navegador sean visibles no afecta tu experiencia de usuario. Como punto positivo, nunca se harán redimensionamientos automáticos que generen efectos visuales raros sin importar cuantas veces los controles se compacten o expandan.
svh
y svw
: small viewport height y small viewport width
La unidad svh
es el porcentaje sobre la altura del viewport pequeño. En el ejemplo, 100svh = 290px
, por lo que 1svh = 2.9px
. Si definimos un contenedor de altura 100svh
se verá perfectamente ajustado al 100% de la pantalla cuando los controles estén visibles (por ejemplo, apenas carga la página). Sin embargo cuando hagas scroll y los controles del navegador se compacten, un contenedor de 100svh
no llegará a ocupar la totalidad del espacio visible.
Es particularmente útil cuando quieres que tu contenedor inicial ocupe el 100% de la pantalla justo al cargar. Cuando el navegador se compacte verás que el contenedor queda un poco más pequeño que el espacio disponible, pero esto no suele ser un problema grave. Como punto positivo al igual que en el caso anterior, nunca se harán redimensionamientos automáticos que generen efectos visuales raros.
dvh
y dvw
: dynamic viewport height y dynamic viewport width
La unidad dvh
a diferencia de las anteriores, es dinámica. Es decir, se adaptará a la visual del navegador en cada momento. En el ejemplo, iniciará en 100dvh = 290px
con 1dvh = 2.9px
. Pero en cuanto el navegador compacte sus controles, los elementos que usen esta medida recalcularán su tamaño pues ahora 100dvh = 320px
con 1dvh = 3.2px
. Si leiste la primera parte, es exactamente el primer comportamiento que tuvieron el dw
y dh
, antes de su redefinición.
Como se mencionó en la primera parte, este comportamiento puede resultar problemático. Si lo usas, debes saber que estas expuesto a cambios de tamaño en tus componentes que pueden generar saltos visuales raros, pero a cambio puedes obtener páginas que se ajustan sin importar el comportamiento del navegador. Un ejemplo es el inicio de esta misma página (si estás leyendo desde un celular, cuando termines puedes pulsar el logo para verlo). El inicio consta de dos vistas, una debajo de la otra, que ocupan cada una el 100% de la pantalla. No importa si el navegador es compacto o no, siempre verás una sección al 100% de la pantalla. Si te fijas detenidamente, verás que cuando el navegador se contrae o se expande hay un pequeño salto, que en este caso he ocultado un poco jugando con las animaciones del scroll. Así que sí es útil y sí puede usarse, pero con precaución.
vmin
y vmax
: Viewport minimum y viewport maximum
Hasta este punto todas las medidas referenciaban o bien a la altura del viewport, o bien a su ancho. Para el vmin
la idea cambia: hace referencia al mínimo entre el vw
y el vh
. Por tanto si tenemos un celular común y lo usamos en modo vertical, 1vmin = 1vw
. Si giramos el celular y lo usamos en modo horizontal, ahora es más ancho que alto y por tanto 1vmin = 1vh
.
El vmax
como podrás imaginarte hace todo lo contrario: equivale al máximo entre el vw
y el vh
, que en celulares comunes en modo vertical viene a significar que 1vmax = 1vh
.
Esta unidad de medida es particualmente útil cuando deseas que un elemento mantenga siempre el mismo tamaño en pantalla sin importar si cambiamos la orientación. Por ejemplo, supongamos que nuestro viewport grande tiene un alto de 320px
y un ancho de 140px
. En modo vertical, el vmin
será igual al vw
, por lo que 100vmin = 140px
. Si giramos el dispositivo a modo horizontal, ahora el alto del viewport grande será de 140px
y el ancho 320px
. Entonces el vmin ahora será relativo al vh
y 100vmin = 140px
, manteniendo el mismo tamaño.
Eso si, aunque resulta muy útil, se cuidadoso al usar esta medida y asegurate de validar tanto en modo horizontal como en modo vertical que el comportamiento sea el esperado.
Existen también medidas como el svmin
, svmax
, lvmin
, lvmax
, dvmin
y dvmax
que basicamente hacen lo mismo, pero tomando como referencia el viewport pequeño, el viewport grande o el viewport dinámico explicados anteriormente.
vi
y vb
: Viewport inline y viewport block
Para estas medidas es necesario explorar dos conceptos:
- Eje en la dimensión de linea: Es el eje que equivale a tu modo de escritura. Para el caso del español, inglés y la mayoría de idiomas que conozco, el eje de escritura es horizontal, de izquierda a derecha.
- Eje en la dimensión de bloque: Es el eje contrario al de linea, por lo cual para nuestro caso es vertical.
Con esto en mente, un vi
equivale al porcentaje sobre el viewport grande en el eje de la dimensión inline. Es decir, para nuestro idioma el vi
es exactamente el mismo lvw
. Por su parte el vb
equivale al porcentaje sobre el viewport grande en el eje de la dimensión de bloque. Entonces para nuestro idioma el vb
es el mismo lvh
. En idiomas en los que la escritura se realiza de forma vertical (como varios idiomas asiáticos) será lo opuesto: 1vi = 1lvh
y 1vb = 1lvw
.
Si tienes un escenario en el que el mismo contenedor pueda soportar idiomas con diferentes tipos de escritura, te puede ser útil esta medida. Sin embargo por experiencia, ese tipo de idiomas cambian tanto la UI que normalmente sus vistas son completamente diferentes, desarrolladas por aparte, así que considero poco común que debas usar estas medidas. Como referencia existen también svi
, svb
, lvi
, lvb
, dvi
y dvb
que como podrás imaginar, equivalen a las que explicamos anteriormente pero siempre con la referencia a los ejes de línea y de bloque.
vw
y vh
: Viewport width y viewport height
Y ahora que existen todas estas medidas, ¿qué ocurre con nuestros clásicos vw
y vh
? Pues nada, siguen y seguirán existiendo. Las medidas anteriormente mencionadas fueron creadas para expandir las posibilidades pero no reemplazan a las originales.
Pero entonces, ¿qué valor toman hoy en día?
Es curioso porque ha variado mucho en el tiempo. Como expliqué en la primera parte, inicialmente se comportaron igual al dvw
y dvh
. Luego Safari decidió cambiarlo, comportandose como el lvw
y lvh
. Cada navegador hizo lo que mejor consideró, y la W3C no colaboró demasiado pues el estandar en su momento solo decía que podía corresponder a las medidas de viewport grande o de viewport pequeño, a elección de cada navegador.
Afortunadamente con el paso del tiempo y frente a la acogida mayoritaria que tuvo la decisión de Safari, la W3C decidió adoptar su solución como la definitiva: El vw
y el vh
corresponden al lvw
y al lvh
, es decir, al ancho y alto respectivamente del viewport grande.
Así que si puedes usar vh
o lvh
indistintamente y tendrán el mismo comportamiento.
Consideraciones finales
- Algo importante a resaltar es que el teclado no es actualmente considerado un elemento de la interfaz del navegador. Por tanto la aparición del teclado no altera el viewport pequeño, ni genera redimensiones en contenedores que usen
dvh
. - En cuanto a la compatibilidad, todas las unidades de medida mencionadas en esta publicación son compatibles con los principales navegadores del mercado.
- Me centré siempre en las medidas de altura y no en las de anchura. En todos los casos, la idea en las medidas de ancho es la misma, solo que practicamente ningún navegador tiene elementos laterales que se compacten/expandan, por lo que las medidas de ancho son casi siempre iguales y usar
vw
suele ser más que suficiente. Eso sí, con el auge de celulares "fold" no sería raro que en un futuro los navegadores empiecen a explorar controles laterales.
Referencias
Si quieres profundizar más en el tema:
- El estandar de la W3C explica en detalle cada una de estas medidas y su utilización.
- En MDN encontramos un resumen completo, no solo de estas medidas sino de todos los valores y unidades válidos en CSS, desde los clásicos pixeles, hasta los extraños
vmin
yvmax
. - En Can I Use podemos ver el detalle de los navegadores que soportan estas medidas. Como lo mencioné previamente, todos los grandes navegadores del mercado las soportan, así que no deberías tener problema en usarlos salvo que tu público objetivo sea un público con navegadores obsoletos.
Si te gustó este artículo, ¡no dudes en compartirlo! Y si encuentras algún error en esta publicación y quieres hacérmelo saber puedes enviarme un email. ¡Hasta la próxima!