Más opciones de fuentes variables para la fuente system-ui de macOS en Chromium 83

Catalina aporta una nueva fuente de sistema variable unida a macOS.

Dominik Röttsches
Dominik Röttsches

La sección "system-ui" de las especificaciones del nivel 4 del módulo de fuentes de CSS define una palabra clave de fuente system-ui que permite a los desarrolladores usar la fuente predeterminada integrada, optimizada con turbo, localizada, de megaalta calidad, no necesaria para descargar y del sistema operativo en sus sitios y apps.

body {
  font-family: system-ui;
}

Esta elección de tipografía es similar a decir "usar la fuente predeterminada del sistema para la configuración regional actual de este usuario".

En macOS, la fuente system-ui es San Francisco, una fuente que un equipo de diseño aprobó y probó y actualizó recientemente. Primero, abordaremos las nuevas y emocionantes funciones de fuentes variables de Catalina y, luego, algunos errores y cómo los ingenieros de Chromium los resolvieron.

En esta publicación, se asume que ya conoces las fuentes variables. Si no es así, consulta Introducción a las fuentes variables en la Web y el siguiente video.

Compatibilidad del navegador

Al momento de escribir, system-ui era compatible con Chromium (desde la versión 56), Edge (desde la versión 79), Safari (desde la versión 11) y con Firefox (desde la versión 43), pero con la palabra clave -apple-system. Consulta ¿Puedo usar fuentes variables? para obtener actualizaciones.

Nuevos poderes

Las nuevas funciones que Catalina aportó a la fuente del sistema ya están disponibles para los desarrolladores web a partir de Chromium 83. La fuente system-ui ahora tiene más opciones de configuración variables: tamaño óptico y 2 ajustes de grosor únicos:

Mojave
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750
  ;
}

Catalina
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750,
    'opsz' 20,
    'GRAD' 400,
    'YAXS' 400
  ;
}

En Mojave, system-ui es una fuente variable con solo una configuración wght. En cambio, system-ui en Catalina es una fuente variable con los parámetros de configuración wght, opsz, GRAD y YAXS.

Me parece que tengo buenas oportunidades de diseño de mejora progresiva. Si lo deseas, profundiza en las sutilezas de la fuente del sistema.

wght

Acepta un grosor de fuente entre 0 y 900, y se aplica de la misma manera a todos los caracteres.

/* 0-900 */
font-variation-settings: 'wght' 750;

opsz

El tamaño óptico es similar al interlineado o al espaciado entre letras, pero el espaciado se realiza mediante un ojo humano en lugar de un cálculo matemático. Un valor igual o inferior a 19 sirve para el espaciado de texto y cuerpo, mientras que 20 o superior sirve para espaciado de encabezados y títulos de visualización.

/* 19 or 20 */
font-variation-settings: 'opsz' 20;

GRAD

Similar al peso, pero sin tocar el espacio horizontal. Acepta valores entre 400 y 1000.

/* 400-1000 */
font-variation-settings: 'GRAD' 500;

YAXS

Estira el glifo verticalmente. Acepta valores entre 400 y 1000.

/* 400-1000 */
font-variation-settings: 'YAXS' 500;

Cómo combinar las opciones

Con algunas líneas de CSS, podemos ajustar la configuración de la fuente a la negrita de nuestra elección o probar otras combinaciones interesantes:

font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;

Así de fácil, los usuarios de Chromium en macOS verán tu peso 750 personalizado actualizado con algunos otros ajustes divertidos 👍.

Área de juegos

Haz clic en Remix to Edit en la sección de Glitch a continuación para obtener una copia editable de ella y, luego, edita las nuevas opciones de font-variation-settings para ver cómo afecta a tu fuente. Recuerda que este Glitch solo funcionará si usas un dispositivo macOS Catalina.

macOS 10.15 agregó funciones nuevas a la fuente del sistema y, en macOS 10.15, se registró un error system-ui complicado en el seguimiento de errores de Chromium. ¡Me pregunto si están relacionados!?

Apéndice: La regresión system-ui

Esta historia comienza con un error diferente: #1005969. Esto se informó en relación con macOS 10.15 porque el espaciado entre fuentes de system-ui se veía angosto y abarrotado.

Una comparación de dos párrafos de una página de grupo de Facebook. A la izquierda está Chrome y a la derecha está Safari, y Chrome es sutil pero un poco más estrecho en el espaciado
Chrome a la izquierda (seguimiento más estricto) y Safari a la derecha (mejor espaciado óptico)

Información general

¿Alguna vez notaste en macOS 10.14 cómo tus párrafos o encabezados se “ajustan” a una fuente diferente cuando el tamaño aumenta o disminuye?

En Mojave (macOS 10.14), la fuente system-ui cambia entre dos fuentes según el tamaño de fuente de destino. Cuando el texto estaba debajo de 20px, macOS usaba “San Francisco Text”. Cuando el texto era 20px o superior, macOS usaba "San Francisco Display". El tamaño óptico se compiló de forma estática en dos fuentes separadas.

Catalina (macOS 10.15) envió una nueva fuente variable unida para San Francisco. Ya no administrará los campos "Texto" y "Anuncio gráfico". También obtuvo el nuevo parámetro de configuración de variación opsz que se describió anteriormente.

h1 {
  font-variation-settings: 'opsz' 20;
}

Lamentablemente, el valor predeterminado opsz en la nueva fuente Catalina es 20 y los ingenieros de Chromium no estaban preparados para aplicar opsz a la fuente del sistema. Esto hacía que los tamaños más pequeños se mostraran demasiado estrechos.

Para solucionar ese problema, Chromium debía aplicar opsz correctamente a la fuente del sistema. Esto provocó que se solucionara el problema n.o 1005969. ¡Victoria! ¿O era...?

Aún sin completar

Aquí es donde el problema se complica: Chromium aplicó opsz, pero algo no se veía bien. En Mac, las fuentes del sistema tienen una tabla de fuentes adicional llamada trak, que ajusta el espaciado horizontal. Mientras trabajaban en la corrección, los ingenieros de Chromium notaron que, en macOS, cuando se recuperaban las métricas horizontales de un objeto CTFontRef, las métricas trak ya se estaban teniendo en cuenta en los resultados de las métricas. La biblioteca de formas de Chromium HarfBuzz necesita métricas en las que los valores trak aún no se tengan en cuenta.

Se muestra la IU del sistema y todo el grosor y las variaciones de la fuente en una lista. La mitad no tiene diferencias de peso aplicadas.
Izquierda: Se aplicaron grosores en negrita a los tamaños de fuente 19 y versiones anteriores. Derecha: Los tamaños de fuente 20 y posteriores pierden el estilo negrita

De forma interna, Skia (la biblioteca de gráficos, no el tipo de letra del mismo nombre) usa tanto la clase CGFontRef de CoreGraphics como la clase CTFontRef de CoreText. Debido a las conversiones internas requeridas entre esos objetos (que se usan para mantener la retrocompatibilidad y acceder a las APIs necesarias en ambas clases), Skia perdería información de peso en ciertas circunstancias y las fuentes en negrita dejarían de funcionar. Esto se realizó en el error #1057654.

Skia aún necesita ser compatible con macOS 10.11 porque Chromium aún lo admite. El 10.11, las fuentes "San Francisco Text" y "San Francisco Display" ni siquiera eran variables. Más bien, cada una era una familia de fuentes independientes para cada grosor disponible. En algún momento, los ID de los glifos dejaron de estar sincronizados entre sí. Por lo tanto, si Skia le dio forma al texto (convirtiendo el texto en glifos que se pueden dibujar) con "Texto de San Francisco", sería un texto incoherente si se dibujó con "San Francisco Display", y viceversa. Incluso si Skia solo pidió un tamaño diferente, macOS podría cambiar al otro. Siempre debería ser posible usar una de las fuentes y solo ajustarla (mediante una matriz para escalarla en lugar de solicitar un tamaño más grande), pero CoreText tiene un problema por el que no escalará los glifos sbix (emoji de color) hacia arriba (solo hacia abajo). Es un poco más complejo que eso. En realidad, CoreText parece limitar la extensión vertical después de la aplicación de la matriz, lo que parece estar relacionado con que no pueda dibujar emojis en ángulos de 45 grados. En cualquier caso, si quieres que tu emoji se muestre en tamaño grande, debes crear una copia de la fuente para obtener una versión grande.

Por lo tanto, para crear copias de objetos CTFont en diferentes tamaños de forma interna y garantizar que se usen los mismos datos de fuente subyacentes, Chromium extrajo el CGFont de CTFont y, luego, creó un nuevo CTFont de CGFont (los objetos CGFont son independientes del tamaño, el cambio mágico ocurre a nivel de CoreText). Esto funcionó bien hasta el 10.154. En 10.15, este recorrido de ida y vuelta terminó perdiendo demasiada información, lo que generó el problema de peso. Flutter notó el problema de peso y se hizo una corrección alternativa para cambiar el tamaño a fin de crear el nuevo CTFont directamente desde el CTFont original y, al mismo tiempo, controlar el tamaño óptico directamente mediante un atributo antiguo pero no documentado en CoreText. Esto hace que las cosas funcionen en la versión 10.11 y corrige otros problemas (como la configuración explícita del tamaño óptico en el valor predeterminado).

Sin embargo, esto conserva más de la "magia" de CoreText en la fuente. Una de ellas parece ser que aún retoca los avances del glifo de otra manera que no es solo la tabla trak (la aplicación de la cual Chromium ya intentaba suprimir a través de otro atributo no documentado).

CGFont no hace nada de esta "magia", por lo que quizás Chromium podría quitar el CGFont de CTFont y solo usarlo para obtener avances. Lamentablemente, esto no funcionaría porque se sabe que CoreText también obstaculiza las fuentes de otras maneras. Por ejemplo, hará que los emojis pequeños sean un poco más grandes de lo que solicitaste (lo que aumentará un poco su tamaño). CGFont no lo sabe, por lo que terminarías con tus emojis basados en Sbix demasiado cerca, ya que medirían en un tamaño, pero CoreText los aumentaría un poco. Chromium quiere que CTFont avance, pero los quiere sin seguimiento y, preferentemente, sin ninguna otra burla.

Dado que la corrección del problema de espaciado requería un conjunto de correcciones interconectadas de Blink y Skia, los ingenieros de Chromium no pudieron "revertir" para solucionar el problema. Los ingenieros de Chromium también intentaron usar una marca de compilación diferente para cambiar una ruta de código relacionada con la fuente en Skia, lo que solucionó el problema de las fuentes en negrita, pero retrocedió el de espaciado.

La solución

Al final, por supuesto, Chromium quería corregir ambos problemas. Chromium ahora recurre a las funciones de métricas de fuente OpenType integradas de HarfBuzz para recuperar métricas horizontales directamente de los datos binarios en las tablas de fuentes de la fuente del sistema. De esta manera, Chromium elude CoreText y Skia cuando la fuente tiene una tabla trak (excepto cuando es la fuente de emojis).

Se muestra la IU del sistema y todo el grosor y las variaciones de la fuente en una lista. La mitad que antes no funcionaba se ve muy bien ahora.

Mientras tanto, todavía existe el problema n.o 10123 de Skia para hacer un seguimiento de la solución en Skia y volver a usar Skia para recuperar las métricas de fuente del sistema desde allí, en lugar de la corrección actual que se realiza en HarfBuzz.