Introducción a las fuentes variables en la Web

Una nueva especificación de fuente que puede reducir significativamente el tamaño de los archivos de fuente

En este artículo, analizaremos qué son las fuentes variables, sus beneficios y cómo podemos usarlas en nuestro trabajo. Primero, revisemos cómo funciona la tipografía en la web y qué innovaciones aportan las fuentes variables.

Compatibilidad del navegador

A partir de mayo de 2020, las fuentes variables son compatibles con la mayoría de los navegadores. Consulta ¿Puedo usar fuentes variables? y Opciones alternativas.

Introducción

Los desarrolladores suelen usar los términos fuente y tipo de letra de forma indistinta. Sin embargo, hay una diferencia: un tipo de letra es el diseño visual subyacente que puede existir en muchas tecnologías de composición tipográfica diferentes, y una fuente es una de estas implementaciones, en un formato de archivo digital. En otras palabras, un tipo de letra es lo que ves y la fuente es lo que usas.

Otro concepto que a menudo se pasa por alto es la distinción entre un estilo y una familia. Un estilo es un tipo de letra único y específico, como cursiva negrita, y una familia es el conjunto completo de estilos.

Antes de las fuentes variables, cada estilo se implementaba como un archivo de fuentes independiente. Con las fuentes variables, todos los estilos pueden estar contenidos en un solo archivo.

Una composición de muestra y una lista de diferentes estilos de la familia Roboto
A la izquierda: un ejemplo de la familia de tipos de letra Roboto. Derecha: Estilos con nombre dentro de la familia.

Desafíos para el diseñador y el desarrollador

Cuando un diseñador crea un proyecto de impresión, se enfrenta a algunas limitaciones, como el tamaño físico del diseño de la página, la cantidad de colores que puede usar (que se determina según el tipo de imprenta que se usará), etcétera. Pero pueden usar tantos estilos de tipografía como desee. Esto significa que la tipografía de los medios impresos suele ser rica y sofisticada, por lo que la experiencia de lectura es realmente encantadora. Piensa en la última vez que disfrutaste navegar en una revista excelente.

Los diseñadores y desarrolladores web tienen restricciones diferentes a las de los diseñadores de impresión, y una importante son los costos de ancho de banda asociados de nuestros diseños. Este ha sido un punto problemático para experiencias tipográficas más enriquecidas, ya que tienen un costo. Con las fuentes web tradicionales, cada estilo que usamos en nuestros diseños requiere que los usuarios descarguen un archivo de fuente independiente, lo que aumenta la latencia y el tiempo de renderización de la página. Solo incluir los estilos normal y negrita, junto con sus equivalentes en cursiva, puede alcanzar 500 KB o más de datos de fuente. Esto sucede incluso antes de que hablemos sobre cómo se renderizan las fuentes, los patrones de resguardo que necesitamos usar o los efectos secundarios no deseados, como FOIT y FOUT.

Muchas familias de fuentes ofrecen una gama de estilos mucho más amplia, desde grosores delgado hasta negro, anchos angostos y anchos, una variedad de detalles estilísticos e incluso diseños específicos de tamaños (optimizados para tamaños de texto grandes y pequeños). Como tendrías que cargar un nuevo archivo de fuente para cada estilo (o combinaciones de estilos), muchos desarrolladores web deciden no usar estas capacidades, lo que reduce la experiencia de lectura de los usuarios.

Anatomía de una fuente variable

Las fuentes variables abordan estos desafíos, ya que empaquetan los estilos en un solo archivo.

Esto funciona comenzando con un estilo central o “predeterminado”, generalmente el “Regular”, un diseño romano vertical con el peso y el ancho más típicos, que se adapta mejor al texto sin formato. Luego, esto se conecta a otros estilos en un rango continuo, denominado "eje". El eje más común es Weight, que puede conectar el diseño predeterminado a través de un diseño en negrita. Cualquier diseño individual se puede ubicar a lo largo de un eje y se denomina "instancia" de la fuente de la variable. El desarrollador de la fuente nombra algunas instancias, por ejemplo, la ubicación 600 del eje de peso se denomina SemiBold.

La fuente variable Roboto Flex tiene tres estilos para su eje Weight. El estilo Regular está en el centro y hay dos estilos en los extremos opuestos del eje: uno más claro y el otro más grueso. Entre estas, puedes elegir entre 900 instancias:

La letra "A" en diferentes pesos
Arriba: Anatomía ilustrada del eje de peso para el tipo de letra Roboto.

El desarrollador de fuentes puede ofrecer un conjunto de diferentes ejes. Puedes combinarlos porque todos comparten los mismos diseños predeterminados. Roboto tiene tres estilos en un eje de ancho: el regular está en el centro del eje y dos estilos, más angosto y más ancho, en cada extremo. Estos proporcionan todos los anchos del estilo Regular y se combinan con el eje Weight para proporcionar todos los anchos para cada peso.

Roboto Flex en combinaciones aleatorias de ancho y peso

Esto significa que hay miles de estilos. Esto puede parecer una sobrecarga masiva, pero la calidad de la experiencia de lectura se puede mejorar notablemente con esta diversidad de estilos de tipos. Además, si no se penaliza el rendimiento, los desarrolladores web pueden usar pocos estilos o tantos como deseen; depende de su diseño.

Cursiva

La forma en que se manejan las cursivas en fuentes variables es interesante, ya que existen dos enfoques diferentes. Los tipos de letra como Helvetica o Roboto tienen contornos compatibles con la interpolación, por lo que sus estilos romano y cursiva se pueden interpolar entre los ejes Slant, que se pueden usar para pasar del romano a la cursiva.

Otros tipos de letra (como Garamond, Baskerville o Bodoni) tienen contornos de glifos romanos y cursivas que no son compatibles con la interpolación. Por ejemplo, los contornos que suelen definir una "n" minúscula romana no coinciden con los contornos que se usan para definir una "n" minúscula en cursiva. En lugar de interpolar un contorno al otro, el eje Cursiva cambia de los contornos romanos a cursivas.

Ejemplo de los ejes de peso para el tipo de letra Amstelvar
Los contornos de la "n" de Amstelvar en cursiva (12 puntos, grosor normal, ancho normal) y en romano. Imagen proporcionada por David Berlow, diseñador de tipografía y tipógrafo en Font Bureau.

Después del cambio a cursiva, los ejes disponibles para el usuario deben ser los mismos que los del romano, al igual que el grupo de caracteres debe ser el mismo.

Una capacidad de sustitución de glifos también se puede ver para glifos individuales y se usa en cualquier lugar del espacio de diseño de una fuente variable. Por ejemplo, un diseño de signo de dólar con dos barras verticales funciona mejor en tamaños de puntos más grandes, pero en tamaños de puntos más pequeños, es mejor un diseño con una sola barra. Cuando tenemos menos píxeles para renderizar el glifo, un diseño de dos barras puede volverse ilegible. Para combatir esto, al igual que el eje cursiva, la sustitución de un glifo por otro puede ocurrir a lo largo del eje Optical Size en un punto que decide el diseñador de tipos.

En resumen, donde los contornos lo permiten, los diseñadores de tipos pueden crear fuentes que interpolan entre varios estilos en un espacio de diseño multidimensional. Esto te brinda un control detallado sobre la tipografía y una gran potencia.

Definiciones de ejes

Existen cinco ejes registrados que controlan características conocidas y predecibles de la fuente: grosor, ancho, tamaño óptico, inclinación y cursiva. Además de ellos, una fuente puede contener ejes personalizados. Estas pueden controlar cualquier aspecto de diseño de la fuente que el diseñador de tipos desea: el tamaño de las serifas, la longitud de los encalados, la altura de los ascendentes o el tamaño del punto en la i.

Si bien los ejes pueden controlar el mismo atributo, pueden usar valores diferentes. Por ejemplo, en las fuentes variables Oswald y Hepta Slab, solo hay un eje disponible, Peso, pero los rangos son diferentes. Oswald tiene el mismo rango que antes de que se actualizara para que fuera variable, de 200 a 700, pero Hepta Slab tiene un peso extremo en 1 que llega hasta 900.

Los cinco ejes registrados tienen etiquetas en minúscula de 4 caracteres que se usan para establecer sus valores en CSS:

Nombres de ejes y valores CSS
Peso wght
Ancho wdth
Inclinación slnt
Tamaño óptico opsz
Cursiva ital

Dado que el desarrollador de fuentes define qué ejes están disponibles en una fuente variable y qué valores pueden tener, es esencial averiguar qué ofrece cada fuente. Esto se debe proporcionar en la documentación de la fuente, o bien puedes inspeccionarla con una herramienta como Wakamai Fondue.

Casos de uso y beneficios

Establecer los valores de los ejes se reduce al gusto personal y a aplicar las prácticas recomendadas tipográficas. El peligro de cualquier tecnología nueva es el posible uso inadecuado, y los parámetros de configuración demasiado artísticos o exploratorios también podrían disminuir la legibilidad del texto. En el caso de los títulos, explorar diferentes ejes para crear grandes diseños artísticos es emocionante, pero para la copia del cuerpo esto implica el riesgo de hacer que el texto sea ilegible.

Expresión emocionante

Ejemplo de césped de Mandy Michael

Un buen ejemplo de expresión artística es una exploración del tipo de letra Decovar de Mandy Michael.

Puedes ver el ejemplo funcional y el código fuente del ejemplo anterior aquí.

Animación

Tipo de letra Zycon, diseñada para animación por David Berlow, diseñador de tipografía y tipógrafo en Font Bureau.

También se puede explorar la animación de personajes con fuentes variables. Arriba se muestra un ejemplo de cómo se utilizan diferentes ejes con el tipo de letra Zycon. Consulta el ejemplo de animación sobre Axis Priaxis en vivo.

Anicons es la primera fuente de íconos de color animados del mundo, basada en íconos de Material Design. Anicons es un experimento que combina dos tecnologías de fuentes de vanguardia: fuentes variables y fuentes de color.

Algunos ejemplos de animaciones de desplazamiento de la fuente del ícono de color de Anicon

Fines

Amstelvar usa pequeños fragmentos de XTRA en direcciones opuestas para que el ancho de las palabras se ordene

Roboto Flex y Amstelvar ofrecen un conjunto de “ejes paramétricos”. En estos ejes, las letras se deconstruyen en 4 aspectos fundamentales de la forma: formas negras o positivas, formas blancas o negativas, y las dimensiones "x" e "y". De la misma manera que los colores primarios se pueden combinar con cualquier otro color para ajustarlo, estos 4 aspectos se pueden usar para ajustar cualquier otro eje.

El eje XTRA en Amstelvar te permite ajustar el valor "blanco" por mil, como se muestra más arriba. Mediante pequeños fragmentos de XTRA en direcciones opuestas, los anchos de las palabras se uniformen.

Fuentes variables en CSS

Cargando archivos de fuentes variables

Las fuentes variables se cargan a través del mismo mecanismo @font-face que las fuentes web estáticas tradicionales, pero con dos mejoras nuevas:

@font-face {
    font-family: 'Roboto Flex';
    src: url('RobotoFlex-VF.woff2') format('woff2-variations');
    src: url('RobotoFlex-VF.woff2') format('woff2') tech('variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
}

1. Formatos de origen: No queremos que el navegador descargue la fuente si no admite fuentes variables, por lo que agregamos descripciones format y tech: una vez en la sintaxis futura (format('woff2') tech('variations')), una vez que esté obsoleta, pero se admita en la sintaxis de navegadores (format('woff2-variations')). Si el navegador admite fuentes variables y admite la sintaxis futura, usará la primera declaración. Si admite fuentes variables y la sintaxis actual, usará la segunda declaración. Ambas apuntan al mismo archivo de fuente.

2. Rangos de estilos: Verás que proporcionamos dos valores para font-weight y font-stretch. En lugar de indicar al navegador qué espesor específico proporciona esta fuente (por ejemplo, font-weight: 500;), ahora le indicamos el rango de espesores admitidos por la fuente. En Roboto Flex, el eje de peso varía de 100 a 1,000, y CSS asigna directamente el rango del eje a la propiedad de diseño font-weight. Si especificas el rango en @font-face, cualquier valor fuera de este rango se “limitará” al valor válido más cercano. El rango del eje de ancho se asigna de la misma manera a la propiedad font-stretch.

Si usas la API de Google Fonts, esto no será posible. El CSS no solo contendrá los formatos y rangos de origen adecuados, sino que Google Fonts también enviará fuentes estáticas de resguardo en caso de que no se admitan las fuentes variables.

Cómo usar pesos y anchos

Actualmente, los ejes que puedes configurar de manera confiable desde CSS son el eje wght a través de font-weight y el eje wdth a font-stretch.

Tradicionalmente, se configuraba font-weight como una palabra clave (light, bold) o como un valor numérico entre 100 y 900, en pasos de 100. Con las fuentes variables, puedes configurar cualquier valor dentro del rango de ancho de la fuente:

.kinda-light {
  font-weight: 125;
}

.super-heavy {
  font-weight: 1000;
}
Se está cambiando el eje de peso de Roboto Flex de su mínimo a su máximo.

Del mismo modo, podemos establecer font-stretch con palabras clave (condensed, ultra-expanded) o con valores porcentuales:

.kinda-narrow {
  font-stretch: 33.3%;
}

.super-wide {
  font-stretch: 151%;
}
Se cambiará el eje de ancho de Roboto Flex de su mínimo a su máximo.

Uso de cursiva y oblicuo

El eje ital está diseñado para las fuentes que contienen un estilo normal y un estilo cursiva. El eje está diseñado para ser un interruptor de encendido/apagado: el valor 0 está desactivado y mostrará el estilo normal, mientras que el valor 1 mostrará la cursiva. A diferencia de otros ejes, no hay transición. Un valor de 0.5 no dará como "media cursiva".

El eje slnt difiere de la cursiva en que no es un diseño nuevo, sino que solo inclina el estilo normal. De forma predeterminada, su valor es 0, lo que significa las formas predeterminadas de letras verticales. Roboto Flex tiene una inclinación máxima de -10 grados, lo que significa que las letras se inclinarán hacia la derecha cuando vayan de 0 a -10.

Sería intuitivo configurar estos eje a través de la propiedad font-style, pero, desde abril de 2020, aún se está definiendo cómo hacerlo. Por el momento, debes tratarlos como ejes personalizados y establecerlos a través de font-variation-settings:

i, em, .italic {
    /* Should be font-style: italic; */
    font-variation-settings: 'ital' 1;
}

.slanted {
    /* Should be font-style: oblique 10deg; */
    font-variation-settings: 'slnt' 10;
}
Se está cambiando el eje de inclinación de Roboto Flex de su mínimo a su máximo.

Cómo usar tamaños ópticos

Un tipo de letra se puede procesar muy pequeño (una nota al pie de 12 px) o muy grande (un título de 80 px). Para responder a estos cambios de tamaño, las fuentes pueden cambiar la forma de las letras para que se adapten mejor a su tamaño. Un tamaño pequeño puede ser mejor sin detalles finos, mientras que un tamaño grande puede beneficiarse con más detalles y trazos más finos.

La letra "a" en diferentes tamaños ópticos
La letra “a” en Roboto Flex en diferentes tamaños de píxeles, luego ajustado para tener el mismo tamaño, muestra las diferencias de diseño. Pruébalo en CodePen

Se introdujo una nueva propiedad de CSS para este eje: font-optical-sizing. De forma predeterminada, está configurado en auto, lo que hace que el navegador establezca el valor del eje en función de font-size. Esto significa que el navegador elegirá automáticamente el mejor tamaño óptico, pero si deseas desactivar esta opción, puedes configurar font-optical-sizing en none.

También puedes configurar un valor personalizado para el eje opsz si deseas intencionalmente un tamaño óptico que no coincida con el tamaño de fuente. La siguiente CSS haría que el texto se mostrara en un tamaño grande, pero en un tamaño óptico como si estuviera impreso en 8pt:

.small-yet-large {
  font-size: 100px;
  font-variation-settings: 'opsz' 8;
}

Usa ejes personalizados

A diferencia de los ejes registrados, los ejes personalizados no se asignarán a una propiedad de CSS existente, por lo que siempre tendrás que configurarlos a través de font-variation-settings. Las etiquetas de los ejes personalizados siempre están en mayúsculas para distinguirlas de los ejes registrados.

Roboto Flex ofrece algunos ejes personalizados, y el más importante es Grade (GRAD). Un eje de calificación es interesante, ya que cambia el grosor de la fuente sin modificar el ancho, de modo que los saltos de línea no cambian. Si juegas con un eje de calificación, puedes evitar tener que manipular los cambios en el eje de peso que afecta el ancho general y, luego, cambiar el eje de ancho que afecta el peso general.

Se está cambiando el eje de calificación de Roboto Flex de su mínimo a su máximo.

Como GRAD es un eje personalizado, con un rango de -200 a 150 en Roboto Flex. Debemos abordarlo con font-variation-settings:

.grade-light {
    font-variation-settings: `GRAD` -200;
}

.grade-normal {
    font-variation-settings: `GRAD` 0;
}

.grade-heavy {
    font-variation-settings: `GRAD` 150;
}

Fuentes variables de Google Fonts

Google Fonts expandió su catálogo con fuentes variables y agregó nuevas con regularidad. Actualmente, el objetivo de la interfaz es elegir instancias individuales de la fuente: debes seleccionar la variación que desees, hacer clic en "Seleccionar este estilo" y se agregará al elemento <link> que recupera el CSS y las fuentes de Google Fonts.

Para usar todos los ejes o rangos de valores disponibles, deberás redactar manualmente la URL en la API de Google Fonts. En la descripción general de las fuentes variables, se enumeran todos los ejes y valores.

La herramienta Google Variable Fonts Links también puede brindarte las URLs más recientes de las fuentes variables completas.

Herencia de la configuración de variación de fuente

Si bien todos los ejes registrados pronto serán compatibles a través de las propiedades de CSS existentes, por el momento, es posible que debas utilizar font-variation-settings como resguardo. Y si tu fuente tiene ejes personalizados, también necesitarás font-variation-settings.

Sin embargo, font-variation-settings tiene un problema. Todas las propiedades que no configures de forma explícita se restablecerán a su valor predeterminado automáticamente. Los valores establecidos anteriormente no se heredan. Esto significa que lo siguiente no funcionará según lo esperado:

<span class="slanted grade-light">
    I should be slanted and have a light grade
</span>

Primero, el navegador aplicará font-variation-settings: 'slnt' 10 desde la clase .slanted. Luego, aplicará font-variation-settings: 'GRAD' -200 desde la clase .grade-light. Sin embargo, esto restablecerá el slnt a su valor predeterminado predeterminado 0. El resultado será texto en grado ligero, pero no inclinado.

Afortunadamente, podemos solucionar esto usando variables de CSS:

/* Set the default values */
:root {
    --slnt: 0;
    --GRAD: 0;
}

/* Change value for these elements and their children */
.slanted {
    --slnt: 10;
}

.grade-light {
    --grad: -200;
}

.grade-normal {
    --grad: 0;
}

.grade-heavy {
    --grad: 150;
}

/* Apply whatever value is kept in the CSS variables */
.slanted,
.grade-light,
.grade-normal,
.grade-heavy {
    font-variation-settings: 'slnt' var(--slnt), 'GRAD' var(--GRAD);
}

Las variables de CSS se transmitirán en cascada, por lo que si un elemento (o uno de sus elementos superiores) configuró slnt en 10, mantendrá ese valor, incluso si configuras GRAD en otro elemento. Consulta Cómo corregir la herencia de fuentes variables para obtener una explicación detallada de esta técnica.

Ten en cuenta que animar variables de CSS no funciona (por diseño), por lo que algo como esto no funciona:

@keyframes width-animation {
   from { --wdth: 25; }
   to   { --wdth: 151; }
}

Estas animaciones tendrán que ocurrir directamente en font-variation-settings.

Mejoras en el rendimiento

Las fuentes variables OpenType nos permiten almacenar diferentes variaciones de una familia de tipos en un solo archivo de fuente. Monotipo ejecutaba un experimento que combinaba 12 fuentes de entrada para generar ocho ponderaciones, en tres anchos, en los estilos cursiva y romano. El almacenamiento de 48 fuentes individuales en un solo archivo de fuentes variable significó una reducción del 88% en el tamaño del archivo.

Sin embargo, si usas una sola fuente, como Roboto Regular, nada más, es posible que no observes una ganancia neta en el tamaño de la fuente si cambias a una fuente variable con muchos ejes. Como siempre, depende de tu caso de uso.

Por otro lado, animar la fuente entre los parámetros de configuración puede causar problemas de rendimiento. Si bien esto mejorará una vez que la compatibilidad de fuentes variables en navegadores evolucione, el problema se puede reducir en cierta medida si solo se animan las fuentes que están actualmente en pantalla. Este práctico fragmento de Dinamo pausa animaciones en elementos con la clase vf-animation cuando no están en pantalla:

var observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(function(entry) {
    // Pause/Play the animation
    if (entry.isIntersecting) entry.target.style.animationPlayState = "running"
    else entry.target.style.animationPlayState = "paused"
  });
});

var variableTexts = document.querySelectorAll(".vf-animation");
variableTexts.forEach(function(el) { observer.observe(el); });

Si la fuente responde a la interacción del usuario, se recomienda regular o desactivar los eventos de entrada. Esto evitará que el navegador renderice instancias de la fuente variable que cambió tan poco en la instancia anterior que el ojo humano no vería la diferencia.

Si usas Google Fonts, es una buena idea conectarte previamente a https://fonts.gstatic.com, el dominio en el que se alojan las fuentes de Google. De esta manera, te asegurarás de que el navegador sepa con anticipación dónde obtener las fuentes cuando las encuentre en el CSS:

<link rel="preconnect" href="https://fonts.gstatic.com" />

Esta sugerencia también funciona para otras CDN: cuanto antes permitas que el navegador configure una conexión de red, más rápido podrá descargar las fuentes.

Encuentra más sugerencias de rendimiento para cargar Google Fonts en The Google Fonts más rápido.

Resguardos y compatibilidad con navegadores

Todos los navegadores modernos admiten fuentes variables. En caso de que necesites admitir navegadores más antiguos, puedes optar por compilar tu sitio con fuentes estáticas y usar fuentes variables como mejora progresiva:

/* Set up Roboto for old browsers, only regular + bold */
@supports not (font-variation-settings: normal) {
  @font-face {
    font-family: Roboto;
    src: url('Roboto-Regular.woff2');
    font-weight: normal;
  }

  @font-face {
    font-family: Roboto;
    src: url('Roboto-Bold.woff2');
    font-weight: bold;
  }

  body {
    font-family: Roboto;
  }

  .super-bold {
    font-weight: bold;
  }
}

/* Set up Roboto for modern browsers, all weights */
@supports (font-variation-settings: normal) {
  @font-face {
    font-family: 'Roboto';
    src: url('RobotoFlex-VF.woff2') format('woff2 supports variations'),
         url('RobotoFlex-VF.woff2') format('woff2-variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
  }

  .super-bold {
    font-weight: 1000;
  }
}

En navegadores más antiguos, el texto con la clase .super-bold se renderizará en negrita normal, ya que es la única fuente en negrita que tenemos disponible. Cuando se admiten fuentes variables, podemos usar el peso más alto de 1,000.

La regla @supports no es compatible con Internet Explorer, por lo que este navegador no mostrará ningún estilo. Si esto representa un problema, siempre puedes usar uno de los trucos antiguos para orientar los anuncios a navegadores relevantes más antiguos.

Si usas la API de Google Fonts, esta se encargará de cargar las fuentes adecuadas para los navegadores de los visitantes. Supongamos que solicitas la fuente Oswald en el rango de grosor de 200 a 700, de esta manera:

<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap" rel="stylesheet">

Los navegadores modernos que admiten fuentes variables obtendrán la fuente variable y tendrán todos los grosores disponibles entre 200 y 700. Los navegadores más antiguos recibirán fuentes estáticas individuales para cada peso. En este caso, esto significa que descargarán 6 archivos de fuente: uno para el grosor de 200, otro para el 300 de peso, y así sucesivamente.

Gracias

Este artículo solo hubiera sido posible con la ayuda de las siguientes personas:

Hero image de Bruno Martins en Unsplash.