Plus d'options de police variables pour la police de l'UI système de macOS dans Chromium 83

Catalina introduit une nouvelle police système à variable unitaire dans macOS.

Dominik Röttsches
Dominik Röttsches

La section "system-ui" des spécifications du module de polices CSS de niveau 4 définit un mot clé de police system-ui qui permet aux développeurs d'utiliser la police intégrée par défaut du système d'exploitation, optimisée, localisée, de très haute qualité, sans téléchargement, directement sur leurs sites et dans leurs applications.

body {
  font-family: system-ui;
}

Ce choix de typographie équivaut à "utiliser la police système par défaut pour les paramètres régionaux actuels de cet utilisateur".

Sous macOS, la police system-ui est San Francisco. Cette police a été validée, testée et récemment mise à jour par une équipe de conception. Nous aborderons d'abord les nouvelles fonctionnalités intéressantes de police variable dans Catalina, puis nous verrons quelques bugs et comment les ingénieurs de Chromium les ont résolus.

Dans cet article, nous partons du principe que vous connaissez déjà les polices variables. Sinon, regardez Introduction aux polices variables sur le Web et à la vidéo ci-dessous.

Compatibilité du navigateur

Au moment de la rédaction de ce document, system-ui est compatible avec Chromium (depuis la version 56), Edge (depuis la version 79), Safari (depuis la version 43) et Firefox (depuis la version 43), mais avec le mot clé -apple-system. Consultez la page Puis-je utiliser des polices variables ? pour en savoir plus.

Nouveaux pouvoirs

Les nouvelles fonctionnalités que Catalina a ajoutées à la police du système sont désormais disponibles pour les développeurs Web depuis Chromium 83. La police system-ui dispose désormais de paramètres plus variables, avec un dimensionnement optique et deux ajustements d'épaisseur uniques :

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
  ;
}

Sur Mojave, system-ui est une police variable avec uniquement des paramètres wght. Sur Catalina, system-ui est une police variable avec des paramètres wght, opsz, GRAD et YAXS.

Cela me semble quelques opportunités de conception d'amélioration progressive intéressante ! Approfondissez vraiment les subtilités de la police du système si vous le souhaitez.

wght

Accepte une épaisseur de police comprise entre 0 et 900, et appliquée de manière égale à tous les caractères.

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

opsz

Le dimensionnement optique est similaire au crénage ou à l’espacement des lettres, mais l’espacement est effectué par un œil humain et non par un calcul mathématique. Une valeur égale ou inférieure à 19 est réservée à l'espacement du texte et du corps du texte, tandis que la valeur 20 ou supérieure correspond à l'espacement pour les en-têtes et les titres à afficher.

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

GRAD

Semblable au poids, mais sans toucher l'espacement horizontal. Il accepte des valeurs comprises entre 400 et 1000.

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

YAXS

Étire le glyphe verticalement. Il accepte des valeurs comprises entre 400 et 1000.

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

Combiner les options

Avec quelques lignes de code CSS, nous pouvons ajuster les paramètres de police en gras ou essayer d'autres combinaisons intéressantes:

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

Et voilà, les utilisateurs de Chromium sur macOS verront votre poids 750 personnalisé mis à niveau avec d'autres ajustements amusants 👍

Aire de jeu

Cliquez sur Remix to Edit (Remixer pour modifier) dans le glitch ci-dessous pour obtenir une copie modifiable du glitch, puis modifiez les nouvelles options font-variation-settings pour voir comment cela affecte votre police. N'oubliez pas que ce Glitch ne fonctionnera que si vous utilisez un appareil macOS Catalina.

macOS 10.15 a ajouté de nouvelles fonctionnalités à sa police système et, dans macOS 10.15, un bug system-ui délicat était consigné dans l'outil de suivi des bugs de Chromium. Je me demande s'ils sont liés !?

Annexe: Régression system-ui

Cette histoire commence par un autre bug: #1005969. Ce problème a été signalé par rapport à macOS 10.15, car l'espacement des polices system-ui semblait étroit et encombré.

Comparaison de deux paragraphes d'une page de groupe Facebook. À gauche, Chrome et Safari à droite. Chrome est subtil, mais légèrement plus espacés.
Chrome à gauche (suivi plus serré), Safari à droite (meilleur espacement optique)

Contexte

Avez-vous déjà remarqué, sous macOS 10.14, comment vos paragraphes ou en-têtes "s'inscrivaient" dans une police différente lorsque la taille augmentait ou baisse ?

Sous Mojave (macOS 10.14), la police system-ui bascule entre deux polices en fonction de la taille de police cible. Lorsque le texte se trouvait sous 20px, macOS utilisait "San Francisco Text". Lorsque le texte comportait 20px ou plus, macOS utilisait "San Francisco Display". Le dimensionnement optique a été intégré de manière statique à deux polices distinctes.

Catalina (macOS 10.15) a expédié une nouvelle police à variable unitaire pour San Francisco. Vous n'avez plus besoin de gérer les annonces textuelles et display. Elle a également obtenu le nouveau paramètre de variante opsz décrit précédemment.

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

Malheureusement, la valeur opsz par défaut dans la nouvelle police Catalina est 20, et les ingénieurs de Chromium n'étaient pas prêts à appliquer opsz à la police du système. Par conséquent, les tailles plus petites s'affichaient trop étroites.

Pour résoudre ce problème, Chromium devait appliquer correctement opsz à la police système. Cela a permis de résoudre le problème n° 1005969. Victoire ! Ou était-ce... ?

Pas encore fait

Le problème est survenu: Chromium a appliqué opsz, mais un élément ne semblait pas encore fonctionner. Les polices système sur Mac disposent d'un tableau de polices supplémentaire appelé trak, qui modifie l'espacement horizontal. Lors de leur résolution, les ingénieurs de Chromium ont remarqué que, sur macOS, lors de la récupération des métriques horizontales à partir d'un objet CTFontRef, les métriques trak étaient déjà prises en compte dans les résultats des métriques. La bibliothèque de formes de Chromium HarfBuzz a besoin de métriques pour lesquelles les valeurs trak ne sont pas encore prises en compte.

Affichage de l'interface utilisateur système, ainsi que de l'épaisseur de la police et des variantes d'une liste. Pour la moitié, aucune différence de poids n'est appliquée.
À gauche: les épaisseurs de police en gras sont appliquées aux tailles de police 19 et inférieures. À droite: les tailles de police supérieures ou égales à 20 perdent en gras

En interne, Skia (la bibliothèque de graphiques, et non la police de caractères du même nom) utilise à la fois la classe CGFontRef de CoreGraphics et la classe CTFontRef de CoreText. En raison des conversions internes requises entre ces objets (utilisées pour maintenir la rétrocompatibilité et accéder aux API nécessaires sur les deux classes), Skia perdait des informations sur le poids dans certaines circonstances et les polices en gras cessent de fonctionner. Cette situation a fait l'objet d'un suivi dans le problème n° 1057654.

Skia doit toujours être compatible avec macOS 10.11, car Chromium la prend toujours en charge. À la version 10.11, les polices "San Francisco Text" et "San Francisco Display" n'étaient même pas des polices variables. Au lieu de cela, chacune constituait une famille de polices distinctes pour chaque épaisseur disponible. Leurs ID de glyphe ne sont plus synchronisés entre eux. Par exemple, si Skia effectuait le lissage du texte (en convertissant le texte en glyphes pouvant être dessinés) avec "San Francisco Text", le texte serait vide de sens s'il était dessiné avec "San Francisco Display", et inversement. Et même si Skia vient de demander une taille différente, macOS peut passer à l'autre. Vous devriez pouvoir toujours utiliser l'une des polices et simplement la mettre à l'échelle (à l'aide d'une matrice au lieu de demander une taille plus grande), mais CoreText rencontre un problème et les glyphes des sbix (emoji de couleur) ne sont pas redimensionnés (uniquement vers le bas). C'est un peu plus complexe que cela. CoreText semble en fait limiter l'étendue verticale après l'application matricielle, qui semble être liée au fait qu'elle ne permet pas de dessiner des emoji à des angles de 45 degrés. Dans tous les cas, si vous souhaitez que vos emoji s'affichent en grand, vous devez copier la police pour en obtenir une version grand format.

Ainsi, pour créer en interne des copies d'objets CTFont de différentes tailles, tout en s'assurant que les mêmes données de police sous-jacentes sont utilisées, Chromium a retiré le CGFont de CTFont, puis a créé un CTFont à partir de CGFont (les objets CGFont sont indépendants de la taille, le changement magique se produit au niveau CoreText). Cela fonctionnait très bien jusqu'aux 10 janvier 154. En 10:15, cet aller-retour a fini par perdre trop d'informations, ce qui a entraîné un problème de poids. Flutter a remarqué le problème de poids. Une autre correction a été apportée au redimensionnement afin de créer la nouvelle CTFont directement à partir de la CTFont d'origine, tout en contrôlant la taille optique directement à l'aide d'un ancien attribut non documenté dans CoreText. Cela permet de continuer à fonctionner dans la version 10.11 et de résoudre d'autres problèmes (par exemple, définir explicitement la taille optique sur la valeur par défaut).

Toutefois, cela permet de préserver une plus grande partie de la "magie" CoreText dans la police. L'une de ces raisons semble être le fait qu'il modifie toujours les progrès du glyphe d'une manière autre que la table trak (application que Chromium essayait déjà de supprimer à l'aide d'un autre attribut non documenté).

CGFont ne fait pas cette "magie", alors peut-être que Chromium pourrait libérer le CGFont du CTFont et se contenter de l'utiliser pour obtenir des avances ? Malheureusement, cela ne fonctionnerait pas, car CoreText est connu pour fonctionner avec des polices d'autres manières. Par exemple, les petits emoji sont légèrement plus grands que ce que vous avez réellement demandé (ce qui augmente légèrement leur taille). CGFont ne sait pas ce faire. Vos emoji basés sur sbix seraient donc trop proches les uns des autres, car vous les mesureriez dans une seule taille, mais CoreText les agrandirait d'une certaine mesure. Chromium souhaite que les CTFont progressent, mais sans suivi, et de préférence sans aucune autre immobilisation.

Étant donné que la résolution du problème d'espacement nécessitait un ensemble de corrections interconnectées pour Blink et Skia, les ingénieurs de Chromium n'ont pas pu "simplement revenir" pour résoudre le problème. Les ingénieurs de Chromium ont également essayé d'utiliser un autre indicateur de compilation pour modifier un chemin de code lié à la police dans Skia. Cela a permis de résoudre le problème des polices en gras, mais de régresser le problème d'espacement.

La solution

Au final, Chromium voulait bien sûr résoudre ces deux problèmes. Chromium utilise désormais les fonctions de métriques de police OpenType intégrées à HarfBuzz pour récupérer les métriques horizontales directement à partir des données binaires dans les tableaux de polices de la police système. Ainsi, Chromium ignore CoreText et Skia lorsque la police comporte une table trak (sauf lorsqu'il s'agit de la police emoji).

Affichage de l'interface utilisateur système, ainsi que de l'épaisseur de la police et des variantes d'une liste. Auparavant, la moitié ne fonctionnait pas. Maintenant, elle est parfaite.

En attendant, il existe toujours le problème n° 10123 de Skia pour suivre la résolution complète de ce problème dans Skia. Vous pouvez ensuite revenir à l'utilisation de Skia pour récupérer les métriques de police système à partir de là, au lieu du correctif actuel qui concerne HarfBuzz.