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

Catalina apporte une nouvelle police de système variable unifiée à macOS.

La section "system-ui" de la spécification 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 du système d'exploitation par défaut intégrée, optimisée, localisée, ultra-haute qualité, sans téléchargement, directement sur leurs sites et applications.

body {
  font-family: system-ui;
}

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

Sur macOS, la police system-ui est San Francisco, une police qu'une équipe de conception a examinée, testée et… récemment mise à niveau. Nous allons d'abord présenter les nouvelles fonctionnalités de polices variables dans Catalina, puis quelques bugs et la façon dont les ingénieurs Chromium les ont résolus.

Dans cet article, nous partons du principe que vous connaissez déjà les polices variables. Si ce n'est pas le cas, consultez Présentation des polices variables sur le Web et la vidéo ci-dessous.

Compatibilité du navigateur

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

Nouveaux pouvoirs

Les nouvelles fonctionnalités apportées à la police système par Catalina sont désormais disponibles pour les développeurs Web à partir de Chromium 83. La police system-ui inclut désormais des paramètres plus variables: une taille optique et deux ajustements de poids 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
  ;
}

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

Il semble que vous ayez des opportunités de conception intéressantes pour l'amélioration progressive. Si vous le souhaitez, vous pouvez vraiment approfondir les subtilités de la police système.

wght

Accepte une épaisseur de police comprise entre 0 et 900 et s'applique de la même manière à tous les caractères.

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

opsz

Le dimensionnement optique est semblable à l'espacement des caractères, mais l'espacement est effectué par un œil humain plutôt que par des calculs. Une valeur de 19 ou inférieure est destinée à l'espacement du texte et du corps du texte, tandis qu'une valeur de 20 ou supérieure est destinée à l'espacement des en-têtes et des titres d'affichage.

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

GRAD

Semblable à l'épaisseur, mais sans modifier l'espacement horizontal. Il accepte les valeurs comprises entre 400 et 1000.

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

YAXS

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

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

Combiner les options

Avec quelques lignes de code CSS, nous pouvons modifier les paramètres de la police pour obtenir un style en gras de notre choix 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 voient votre poids de 750 pixels amélioré et personnalisé, ainsi que d'autres ajustements amusants 👍

Aire de jeu

Cliquez sur 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 elles affectent 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. Dans macOS 10.15, un bug system-ui délicat a été enregistré dans le bug tracker Chromium. Je me demande s'ils sont liés.

Annexe : Régression system-ui

Cette histoire commence par un autre bug : numéro 1005969. Ce problème a été signalé pour macOS 10.15, car l'espacement de la police system-ui semblait étroit et serré.

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

Contexte

Avez-vous déjà remarqué, sous macOS 10.14, que vos paragraphes ou en-têtes passaient à une police différente lorsque la taille augmentait ou diminuait ?

Sous Mojave (macOS 10.14), la police system-ui alternait 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 était supérieur ou égal à 20px, macOS utilisait "San Francisco Display". Le dimensionnement optique a été intégré de manière statique dans deux polices distinctes.

Catalina (macOS 10.15) a fourni une nouvelle police variable unifiée pour San Francisco. Vous n'avez plus besoin de gérer les campagnes textuelles et display. Elle dispose également du 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 Chromium n'étaient pas prêts à appliquer opsz à la police système. Cela entraînait un affichage trop étroit des tailles plus petites.

Pour résoudre ce problème, Chromium devait appliquer correctement opsz à la police système. Le problème 1005969 a ainsi été résolu. Victoire ! Ou était-ce… ?

Pas encore fait

C'est là que les choses se sont compliquées: Chromium a appliqué opsz, mais quelque chose ne semblait pas correct. Les polices système sur Mac disposent d'une table de polices supplémentaire appelée trak, qui ajuste l'espacement horizontal. Alors qu'ils travaillaient sur le correctif, les ingénieurs Chromium ont remarqué que, sous macOS, lorsque les métriques horizontales étaient récupérées à 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 mise en forme de Chromium HarfBuzz nécessite des métriques dans lesquelles les valeurs trak ne sont pas encore prises en compte.

Affichage de system-ui et de toutes ses épaisseurs de police et variantes dans une liste. La moitié d'entre eux n'appliquent aucune différence de poids.
À gauche: épaisseurs de police en gras appliquées aux tailles de police 19 et inférieures. À droite: les polices de taille 20 et supérieures perdent un style en gras.

En interne, Skia (la bibliothèque graphique, et non la police de 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 conserver la rétrocompatibilité et accéder aux API nécessaires dans les deux classes), Skia perdait des informations de poids dans certaines circonstances et les polices en gras ne fonctionnaient plus. Ce problème a été suivi dans le problème 1057654.

Skia doit toujours être compatible avec macOS 10.11, car Chromium l'est toujours. Le 11 octobre, les polices "San Francisco Text" et "San Francisco Display" n'étaient même pas des polices variables. Il s'agissait plutôt d'une famille de polices distinctes pour chaque épaisseur disponible. À un moment donné, leurs ID de glyphes ne sont plus synchronisés. Par conséquent, si Skia a effectué la mise en forme du texte (conversion du texte en glyphes pouvant être dessinés) avec "San Francisco Text", le texte serait illisible s'il était dessiné avec "San Francisco Display", et vice-versa. Et même si Skia a demandé une taille différente, macOS peut passer à l'autre. Il devrait être possible d'utiliser toujours l'une des polices et de simplement la mettre à l'échelle (à l'aide d'une matrice pour l'agrandir au lieu de demander une taille plus grande), mais CoreText présente un problème qui ne permet pas d'agrandir les glyphes sbix (emoji couleur) (seulement de les réduire). C'est un peu plus compliqué que ça. CoreText semble en fait limiter l'étendue verticale après l'application de la matrice, ce qui semble lié au fait qu'il ne peut pas dessiner d'emoji à 45 degrés. Dans tous les cas, si vous souhaitez que vos emoji s'affichent en grand, vous devez créer une copie de la police pour obtenir une version agrandie.

Pour créer en interne des copies d'objets CTFont de différentes tailles tout en veillant à utiliser les mêmes données de police sous-jacentes, Chromium a extrait le CGFont du CTFont, puis créé un nouveau CTFont à partir du CGFont (les objets CGFont sont indépendants de la taille, le changement magique se produit au niveau de CoreText). Cela fonctionnait correctement jusqu'à la version 10.154. Dans la version 10.15, ce trajet aller-retour a perdu trop d'informations, ce qui a entraîné le problème de poids. Flutter a remarqué le problème de poids et une autre solution de redimensionnement a été apportée pour créer le nouveau CTFont directement à partir du CTFont d'origine, tout en contrôlant directement la taille optique à l'aide d'un ancien attribut non documenté dans CoreText. Cela permet de continuer à utiliser la version 10.11 et de résoudre d'autres problèmes (comme la définition explicite de la taille optique sur la valeur par défaut).

Toutefois, cela préserve davantage la "magie" de CoreText dans la police. L'une d'elles semble être qu'il modifie toujours les avances de glyphe d'une manière autre que la table trak (dont Chromium essayait déjà de supprimer l'application via un autre attribut non documenté).

CGFont n'effectue aucune de ces "magies". Chromium pourrait-il retirer CGFont de CTFont et l'utiliser uniquement pour obtenir des avances ? Malheureusement, cela ne fonctionnerait pas, car CoreText est également connu pour interférer avec les polices d'autres manières. Par exemple, il rend les petits emoji légèrement plus grands que vous ne l'avez demandé (en augmentant légèrement leur taille). CGFont ne le sait pas. Vous vous retrouveriez donc avec des emoji basés sur sbix trop proches les uns des autres, car vous mesureriez une taille, mais CoreText les dessinerait plus grands. Chromium souhaite les avancées de CTFont, mais sans suivi et de préférence sans autre manipulation.

É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 "se contenter de revenir" pour résoudre le problème. Les ingénieurs Chromium ont également essayé d'utiliser un autre indicateur de compilation pour modifier un chemin de code lié aux polices dans Skia, ce qui a résolu le problème des polices en gras, mais a aggravé le problème d'espacement.

Solution

Bien sûr, Chromium a voulu résoudre les 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 des tables de polices de la police système. Ainsi, Chromium contourne CoreText et Skia lorsque la police comporte une table trak (sauf lorsqu'il s'agit de la police emoji).

Affichage de system-ui et de toutes ses épaisseurs de police et variantes dans une liste. La moitié qui ne fonctionnait pas auparavant est maintenant parfaite.

En attendant, il reste le problème Skia n° 10123 pour suivre la résolution de ce problème dans Skia, et pour revenir à l'utilisation de Skia pour récupérer les métriques des polices système à partir de là, au lieu de la correction actuelle proposée par HarfBuzz.