El zoom, el factor de respuesta y WCAG
Por qué una tipografía que solo depende de vw no responde al ajuste de tamaño de texto, cómo calcular exactamente cuánto responde la tuya, y qué parte del clamp da la garantía.
Una escala fluida mal construida no es un defecto estético: deja fuera a quien necesita el texto más grande. Y no se detecta mirando, porque en la pantalla del que la escribió se ve bien. Se detecta con una cuenta de tres líneas que dice exactamente qué porcentaje de tu tamaño de fuente responde a la preferencia del usuario, y esa cuenta debería formar parte de la revisión de cualquier sistema tipográfico.
- Distinguir el zoom de página del ajuste de tamaño de texto y su efecto sobre
vw. - Calcular el factor de respuesta de una expresión fluida.
- Predecir el tamaño resultante al duplicar el tamaño de fuente de la raíz.
- Justificar por qué los dos topes del
clampdeben ir enrem.
Dos formas distintas de agrandar el texto
El navegador ofrece dos mecanismos que la gente confunde y que se comportan de forma opuesta frente a las unidades de viewport.
El zoom de página cambia la relación entre píxeles CSS y píxeles físicos. Todo crece a la vez: cajas, imágenes, bordes y también el viewport medido en píxeles CSS, que se encoge. Con zoom al 200%, una ventana de 1280 píxeles físicos pasa a medir 640 píxeles CSS, así que 1vw vale 6.4 en lugar de 12.8. El texto en vw no crece: crece la escala de todo el dibujo. El resultado visual es correcto, pero fíjate en lo que ha pasado con la tipografía fluida: al reducirse el viewport, la fórmula devuelve un tamaño menor y el zoom lo compensa. El usuario acaba con el tamaño de la versión estrecha, ampliado.
El ajuste de tamaño de fuente cambia el valor de 1rem sin tocar el píxel CSS ni el viewport. Es el ajuste que usa quien quiere el texto más grande sin que se le agranden las imágenes, los controles y los mapas; es el que viene configurado de fábrica en muchos sistemas para personas con baja visión, y es el que la mayoría de los desarrolladores no ha probado nunca. Frente a este ajuste, un término en vw no se mueve ni un píxel.
El criterio 1.4.4 de las WCAG exige que el texto se pueda ampliar hasta el 200% sin pérdida de contenido ni de funcionalidad. Un font-size: 2.5vw no responde en absoluto a la segunda vía, y las auditorías lo tratan como fallo. La corrección no es añadir un aviso ni una clase alternativa: es que el valor contenga un término que crezca con la raíz.
El factor de respuesta
Escribe el valor preferido como en la derivación de la recta: S = A·R + B·V/100, con R el tamaño de fuente de la raíz y V el ancho del viewport.
Define el factor de respuesta como la fracción del tamaño que aporta el término en rem:
f = (A x R) / (A x R + B x V / 100)
Si el usuario multiplica el tamaño de fuente de la raíz por k, el término en rem se multiplica por k y el de vw no cambia, así que el tamaño resultante es:
S(k) / S(1) = 1 + f x (k - 1)
Con k = 2, la fórmula se reduce a 1 + f. El texto crece un f por uno. Si f vale 1 —solo rem— el texto duplica. Si vale 0 —solo vw— no se mueve. Y si vale 0.55, el usuario que ha pedido el doble obtiene un 55% más.
Los números de la escala de la lección anterior, clamp(1.125rem, 0.869rem + 1.136vw, 1.75rem), evaluada en un viewport de 1024 píxeles con la raíz por defecto:
termino rem : 0.869 x 16 = 13.90 px
termino vw : 1.136 x 10.24 = 11.63 px
tamano : 25.54 px
f : 13.90 / 25.54 = 0.545
al 200% : 25.54 x 1.545 = 39.4 px
Un 54% de crecimiento donde el usuario pidió un 100%. No es un aprobado, pero es un mundo respecto al 0% de la versión con vw puro, y es un número que puedes enseñar y discutir en lugar de una opinión.
La regla práctica que sale de aquí: mantén f por encima de 0.5 en el ancho más grande donde el clamp siga interpolando. Es el peor punto, porque el término en vw es máximo justo ahí.
Lo que garantiza cada parte del clamp
Aquí está la parte que casi nadie ve, y es la razón por la que los topes deben ir en rem.
Fuera del intervalo, el factor de respuesta es 1. Cuando el clamp está pegado a su mínimo o a su máximo y esos topes están en rem, el tamaño es puro rem: responde al 100% al ajuste del usuario. Es decir, la tipografía fluida solo tiene un problema de accesibilidad dentro de su banda de interpolación, y en los extremos se comporta perfectamente.
Y ahora la consecuencia interesante: al aumentar el tamaño de fuente de la raíz, los dos topes se mueven con él, así que la banda de interpolación se desplaza hacia arriba y el usuario sigue teniendo margen. El tope superior no es solo un freno estético para que los titulares no se desmadren; es el mecanismo que devuelve la respuesta completa al zoom en cuanto la fórmula se sale del intervalo.
Compara con la versión que muchos escriben sin pensar, con el tope en píxeles:
/* mal: el tope superior no escala con el usuario */
.titulo { font-size: clamp(1.125rem, 0.869rem + 1.136vw, 28px); }
Con la raíz a 32px y un viewport de 1024, el valor preferido sube a 39.4px, pero el máximo sigue siendo 28px. El usuario que ha pedido el doble de texto obtiene 28 / 25.54 = 1.10, un 10% más. La expresión ha pasado de responder a medias a no responder casi nada, y el único cambio ha sido una unidad en el tercer argumento.
Un tope en px, en vw o en cqi anula la garantía. En px congela el techo mientras el usuario crece. En unidades de viewport o de contenedor no acota nada, porque los tres términos se mueven juntos, y además elimina cualquier respuesta al ajuste de tamaño de fuente. La forma correcta no tiene variantes: mínimo en rem, máximo en rem, y el vw solo dentro del término del medio.
El procedimiento de comprobación
Cuatro pasos, todos manuales, todos rápidos, y ninguno sustituible por una herramienta.
Uno: pon el tamaño de fuente del navegador al doble. En las preferencias, no con el zoom. En Firefox y en Chrome es un desplegable con valores; elige 32 píxeles o el equivalente a “muy grande”.
Dos: mide en tres anchos. El estrecho, el ancho de diseño y uno intermedio. En la consola, getComputedStyle(document.querySelector('h1')).fontSize te da el valor real sin discutir.
Tres: divide. Compara cada valor con el mismo ancho a 16px de raíz. Si algún cociente baja de 1.5, tienes demasiado vw en esa zona y toca subir el término constante bajando la pendiente.
Cuatro: comprueba que el layout aguanta. Un texto que crece un 50% dentro de una caja de altura fija se desborda o se recorta, y eso es “pérdida de contenido” en el sentido literal del criterio. La escala tipográfica y las alturas fijas no conviven.
Casi todo el mundo pone el tercer argumento del clamp porque no quiere que el titular ocupe media pantalla en un monitor de 34 pulgadas. Es una razón de diseño y es suficiente para que lo escriba, y por eso casi nadie descubre que ese argumento hace un trabajo mucho más importante: es lo que devuelve al usuario el control total sobre el tamaño del texto en cuanto la fórmula se sale del intervalo. Hay una moraleja de ingeniería escondida ahí, y es incómoda. La accesibilidad de esa expresión no depende de que nadie haya pensado en accesibilidad; depende de una convención que se sostiene por otro motivo, y esa clase de garantía es exactamente la que se rompe en la primera refactorización, cuando alguien cambia el tope a px porque le cuadraba mejor con el diseño de Figma y todo sigue viéndose igual en su pantalla. Las propiedades importantes que dependen de convenciones no escritas no son propiedades, son suerte. La forma de convertir la suerte en garantía es que el sistema tipográfico viva en cuatro custom properties documentadas, que un comentario diga por qué los topes están en rem, y que el procedimiento de las cuatro comprobaciones esté en la lista de revisión del componente. Nada de eso es CSS; todo eso es lo que hace que el CSS siga siendo correcto dentro de dos años.
- Coge la expresión de
font-sizedelh1de un proyecto tuyo y descompón sus términos enAyB. - Calcula
fa 1280 píxeles de viewport y predice el tamaño con la raíz a 32px. - Comprueba la predicción en el navegador con
getComputedStyle. - Cambia el tope superior a su valor equivalente en
pxy repite: anota la diferencia. - Si
fno llega a 0.5, mueve los dos puntos de diseño —subir el tamaño en el ancho pequeño es lo que más baja la pendiente— y vuelve a derivar la recta hasta que lo supere.