Unidades lógicas: vi, vb y el eje que cambia
Qué significan las unidades de viewport en el eje en línea y en el de bloque, cuándo su valor deja de coincidir con vw y vh, y cómo mantener una política de unidades coherente.
vw y vh están atadas a la pantalla: ancho es ancho y alto es alto. En cuanto un bloque de texto cambia de modo de escritura, esa correspondencia se rompe, y lo que era “la dirección en la que fluye el texto” pasa a ser la vertical. vi y vb expresan la misma medida en términos del flujo en lugar de en términos del monitor, y con eso un componente sobrevive a un cambio de modo de escritura sin tocar una línea.
- Distinguir el eje en línea del eje de bloque en cada modo de escritura.
- Traducir entre unidades físicas y lógicas de viewport.
- Identificar los casos donde el valor de
viyvwdeja de coincidir. - Definir una política de unidades coherente para un proyecto.
El eje lógico frente al eje físico
CSS tiene dos sistemas de ejes en paralelo. El físico habla de arriba, abajo, izquierda y derecha. El lógico habla de dos ejes definidos por el flujo del contenido:
- El eje en línea es la dirección en la que se colocan las palabras dentro de una línea.
- El eje de bloque es la dirección en la que se apilan las líneas y los bloques.
En español, y en el modo horizontal-tb que es el predeterminado, el eje en línea es horizontal y el de bloque es vertical, así que en línea coincide con ancho y bloque con alto. En vertical-rl, que es el modo del japonés y el chino tradicionales, se intercambian: el texto baja por la columna, así que el eje en línea es vertical y el de bloque es horizontal.
Las unidades
| física | lógica | mide |
|---|---|---|
vw |
vi |
el 1% del viewport en el eje en línea |
vh |
vb |
el 1% del viewport en el eje de bloque |
Y se combinan con los tres viewports de la lección anterior, dando la matriz completa: svi, lvi, dvi, svb, lvb, dvb. El soporte es el mismo que el de sus parientes físicas: Safari 15.4, Firefox 101 y Chrome 108.
No hay versión lógica de vmin y vmax porque no la necesitan: ya son independientes del eje por definición, toman la menor y la mayor de las dos dimensiones sea cual sea el modo de escritura.
.hoja-lateral {
inline-size: min(90vi, 32rem);
block-size: 100svb;
padding-inline: 2vi;
}
Ese bloque no menciona ancho ni alto en ningún sitio, y por eso da el resultado correcto en un modo de escritura vertical sin cambiar nada.
Cuándo cambia de verdad el resultado
Aquí conviene ser honesto, porque la recomendación de “usa siempre unidades lógicas” se repite sin matizar y la mayor parte del tiempo no cambia absolutamente nada. En un sitio en español, vi es idéntica a vw en todos los dispositivos y en todos los estados. Cero diferencia.
Los casos donde sí cambia son tres, y solo tres.
El documento entero está en un modo de escritura vertical. Una edición japonesa, un sitio en chino tradicional maquetado a la manera clásica. Aquí el cambio afecta a todo y las unidades lógicas son sencillamente las correctas.
Un componente concreto rota. Este es el caso interesante y el que aparece en proyectos occidentales: una etiqueta vertical en el lomo de una tarjeta, el título de un eje en una gráfica, una pestaña lateral. Se hacen con writing-mode: vertical-rl o sideways-lr sobre un elemento suelto, y dentro de ese elemento el eje en línea es la vertical de la pantalla.
.lomo {
writing-mode: vertical-rl;
block-size: max-content; /* es el ancho en pantalla */
inline-size: min(60vi, 40ch); /* es la altura en pantalla */
padding-block: 0.5em; /* separacion horizontal en pantalla */
}
Si ese componente estuviera escrito con width, height y vw, todas las medidas apuntarían al eje equivocado y habría que invertirlas a mano, con el resultado de que el componente ya no es reutilizable en un contexto horizontal.
La dirección es de derecha a izquierda. El árabe y el hebreo usan direction: rtl con el eje de bloque intacto, así que vi sigue siendo la horizontal. Lo que cambia no son las unidades sino el sentido: inset-inline-start pasa a ser el borde derecho. Las unidades lógicas no arreglan eso por sí solas; lo arreglan las propiedades lógicas.
Una política de unidades coherente
La conclusión práctica no es “usa lógicas siempre” ni “no te molestes”. Es que las unidades lógicas cuestan lo mismo de escribir que las físicas y solo pueden ganar, así que la decisión racional es tomarlas por defecto y reservar las físicas para cuando la medida se refiera de verdad a la pantalla.
Una política que funciona bien en un equipo:
- Lógicas por defecto en todo lo que tenga que ver con contenido de texto: tamaños de caja de componentes, separaciones internas, medidas de línea, dimensionado de paneles.
- Físicas cuando la medida es del dispositivo: la altura de una portada a pantalla completa se refiere a la pantalla, no al flujo, y
100svhcomunica eso mejor que100svb. Una imagen de fondo que debe cubrir la ventana igual. vminyvmaxsin complejos: no tienen versión lógica porque no la necesitan, y siguen siendo la forma correcta de dimensionar algo que debe caber independientemente de la orientación.
La misma lógica se aplica al resto del lenguaje: inline-size y block-size frente a width y height, padding-inline frente a padding-left y padding-right, inset-block-start frente a top. Las unidades son la última pieza de un sistema que ya estaba completo en las propiedades.
Un % no se resuelve contra el viewport sino contra el bloque contenedor, y cada propiedad decide contra qué dimensión del contenedor. padding-block: 10% se resuelve contra el ancho del contenedor, no contra el alto, lo cual sorprende siempre. Las unidades de viewport no tienen ese problema: 10vb es siempre el 10% del viewport en el eje de bloque, sin excepciones por propiedad.
El argumento habitual a favor de las unidades y propiedades lógicas —“por si algún día internacionalizas”— es malo, porque casi nadie internacionaliza a japonés vertical y todo el mundo lo sabe. El argumento bueno es otro y aparece dentro de proyectos monolingües: cada vez que rotas un elemento, has creado un contexto local con otro eje, y el CSS escrito en términos físicos deja de significar lo que dice justo ahí. Una etiqueta vertical, un encabezado de tabla girado, un carrusel que cambia de orientación en móvil, un componente que se reutiliza en una barra lateral vertical: todos son cambios de eje locales, todos ocurren en proyectos que jamás se traducirán, y en todos el CSS lógico simplemente funciona mientras el físico exige una versión aparte. Es la misma economía que las unidades relativas: no pagas nada por escribir inline-size en lugar de width, y el día que cobras, cobras entero. La diferencia entre un ingeniero que ha sufrido esto y uno que no es que el primero ya no lo ve como una preparación para un futuro improbable, sino como la forma de decir con precisión lo que quiere decir hoy.