wandres.dev
FUENTES VARIABLES · Ejes y font-variation-settings

Los ejes registrados y los personalizados

wght, wdth, slnt, ital y opsz con sus rangos, sus unidades y la propiedad CSS que los controla; los ejes propios de cada fuente y el que no cambia la métrica.

⏱ 16 min

OpenType reserva cinco etiquetas de eje en minúsculas y deja el resto del espacio, en mayúsculas, para lo que quiera el tipógrafo. Los cinco registrados tienen una propiedad de CSS que los controla; los personalizados solo son accesibles con la propiedad de bajo nivel. Y entre los personalizados hay uno que aparece en muchas familias y resuelve un problema que el eje de peso no puede resolver.

🎯 Al terminar esta lección sabrás
  • Asociar cada eje registrado con su propiedad de CSS y su rango típico.
  • Evitar los dos errores de signo y unidad que producen resultados invertidos.
  • Reconocer los ejes personalizados y saber cómo se descubren.
  • Explicar qué gana un eje de grado frente al eje de peso.

Los cinco registrados

eje propiedad de CSS rango habitual qué cambia
wght font-weight 1 a 1000 el grosor de los trazos
wdth font-stretch 50% a 200% la anchura de los glifos
slnt font-style: oblique Ndeg grados la inclinación mecánica
ital font-style: italic 0 o 1 el cambio a formas cursivas
opsz font-optical-sizing en puntos el ajuste por tamaño óptico

Que estén registrados significa dos cosas: que la especificación de CSS Fonts define cómo se traduce cada propiedad de alto nivel a su valor de eje, y que el navegador puede aplicar esa traducción sin saber nada de la fuente concreta. Un eje personalizado no tiene esa traducción y por eso solo se alcanza con font-variation-settings.

Una nota de nomenclatura: font-stretch se está renombrando a font-width en la especificación. El nombre nuevo todavía tiene soporte muy desigual —el descriptor font-width en @font-face solo está en Safari 18.4—, así que la forma interoperable en 2026 sigue siendo font-stretch. Los dos nombres significan lo mismo y con el tiempo font-stretch quedará como alias.

Los dos errores de signo y unidad

El signo de slnt está invertido respecto a CSS. El eje se define en grados en sentido antihorario desde la vertical, así que la inclinación normal hacia la derecha es un valor negativo: slnt a -10 inclina a la derecha. En CSS, en cambio, font-style: oblique 10deg es positivo para esa misma inclinación. El navegador hace la conversión sin que te enteres; si escribes font-variation-settings: 'slnt' 10 esperando una cursiva, obtienes el texto inclinado hacia atrás.

wdth es un número, no un porcentaje. En CSS escribes font-stretch: 87.5%; en font-variation-settings el valor es 'wdth' 87.5, sin el símbolo. Poner el porcentaje ahí invalida la declaración entera y como es una lista, se pierden también los demás ejes de esa declaración.

opsz se expresa en puntos. Su rango típico va de 8 a 144 y corresponde a tamaños tipográficos, no a píxeles.

Estos tres detalles son, por sí solos, un argumento para no tocar font-variation-settings cuando existe la propiedad de alto nivel: la propiedad conoce las unidades y los signos, y tú no tienes por qué.

Los ejes personalizados

Se identifican con cuatro letras en mayúsculas y los define quien dibujó la fuente. Los que aparecen con más frecuencia:

  • GRAD, grado: cambia el grosor sin cambiar los anchos de avance.
  • CASL, casual: interpola entre un dibujo formal y uno informal.
  • MONO, monoespaciado: interpola entre proporcional y de ancho fijo.
  • CRSV, cursiva: controla de forma continua cuánto se acercan las formas a las cursivas.
  • XOPQ, YOPQ, YTAS y familia: ejes paramétricos que exponen dimensiones internas del dibujo.

No hay forma de descubrirlos desde CSS. Se leen del archivo:

python3 -m fontTools.ttx -t fvar -o - fuente.woff2

La tabla fvar lista cada eje con su etiqueta, su mínimo, su máximo y su valor por defecto, además de las instancias nombradas. Es el primer comando que conviene ejecutar al recibir una fuente variable, porque el rango real casi nunca coincide con el que el proveedor anuncia.

GRAD y el eje que no cambia la métrica

De todos los ejes personalizados, GRAD merece una sección propia porque resuelve un problema concreto que ningún eje registrado resuelve.

Cuando aumentas wght, los trazos engordan y los avances horizontales crecen con ellos: la palabra ocupa más, la línea se recompone y el párrafo puede cambiar de altura. Por eso un efecto de hover que engorde el texto de un enlace mueve el texto de alrededor, y por eso animar font-weight en una lista larga es caro: cada fotograma dispara layout.

GRAD está diseñado para engordar los trazos manteniendo las métricas. El glifo ocupa exactamente lo mismo, así que no hay recomposición: solo cambia el color de la mancha de texto.

@property --grado {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

.enlace {
  font-variation-settings: 'GRAD' var(--grado);
  transition: --grado 150ms ease-out;
}
.enlace:hover,
.enlace:focus-visible {
  --grado: 140;
}

Fíjate en el patrón: el eje se compone a partir de una custom property registrada, no se escribe el valor directamente en la transición. Eso hace dos cosas a la vez: la propiedad registrada es interpolable, con lo que la transición es suave, y el eje pasa a cascadear como una propiedad independiente. Es el patrón correcto para cualquier eje personalizado.

⚠️
Comprueba el rango antes de usar un eje personalizado

Los ejes personalizados no tienen rango estándar. GRAD puede ir de -200 a 150 en una familia y de 0 a 1 en otra. Un valor fuera de rango no invalida la declaración: el motor lo recorta al extremo más cercano, con lo que el efecto simplemente no se ve o se ve al máximo. Si has escrito un valor y no pasa nada, mira la tabla fvar antes de buscar en otro sitio.

El eje que no toca la métrica convierte una animación de layout en una de pintado

Hay una jerarquía de coste en el motor de render que se aplica a todo, y las fuentes variables la ilustran con una nitidez poco común: animar wght es una animación de layout y animar GRAD es una animación de pintado, y entre las dos hay un orden de magnitud largo de diferencia. La razón es exactamente la misma que hace que animar width cueste cien veces más que animar transform: una cambia las cajas y obliga a rehacer la composición del texto, la otra solo cambia los píxeles dentro de cajas que ya están donde estaban. Lo interesante es que aquí la elección no la ofrece el navegador sino el tipógrafo, que al incluir un eje de grado en la fuente está tomando una decisión de rendimiento en el archivo binario, años antes de que tú escribas el CSS. Es un recordatorio de que la frontera entre diseño e ingeniería es mucho más porosa de lo que parece, y de que merece la pena preguntar por GRAD al evaluar una familia variable para un producto con muchos estados interactivos: no es un capricho tipográfico, es la diferencia entre un hover que se puede animar y uno que no.