Ulteriori opzioni variabili per il carattere dell'interfaccia utente di sistema macOS in Chromium 83

Catalina introduce in macOS un nuovo carattere di sistema variabile unificato.

La sezione "system-ui" della specifica del Modulo dei caratteri CSS di livello 4 definisce una parola chiave del carattere system-ui che consente agli sviluppatori di utilizzare il carattere del sistema operativo predefinito integrato, ottimizzato, localizzato, di altissima qualità e senza download direttamente nei loro siti e nelle loro app.

body {
  font-family: system-ui;
}

Questa scelta di tipografia è simile a "usa il carattere di sistema predefinito per le impostazioni internazionali correnti dell'utente".

Su macOS, il carattere system-ui è San Francisco, un carattere che un team di design ha verificato, testato e... recentemente aggiornato. Per prima cosa parleremo delle nuove e interessanti funzionalità dei caratteri variabili in Catalina, poi parleremo di un paio di bug e di come gli ingegneri di Chromium li hanno risolti.

Questo post presuppone che tu abbia già familiarità con i caratteri variabili. In caso contrario, consulta la pagina Introduzione ai caratteri variabili sul web e guarda il video di seguito.

Compatibilità del browser

Al momento della stesura di questo articolo, system-ui è supportato da Chromium (dalla versione 56), Edge (dalla versione 79), Safari (dalla versione 11) e da Firefox (dalla versione 43), ma con la parola chiave -apple-system. Per gli aggiornamenti, consulta l'articolo Posso utilizzare caratteri variabili?.

Nuovi poteri

Le nuove funzionalità che Catalina ha apportato al carattere di sistema sono ora disponibili per gli sviluppatori web a partire da Chromium 83. Il carattere system-ui ora ha più impostazioni variabili: dimensioni ottiche e due regolazioni dello spessore uniche:

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

Su Mojave, system-ui è un carattere variabile con solo le impostazioni di wght. Mentre system-ui su Catalina è un carattere variabile con impostazioni wght, opsz, GRAD e YAXS.

A mio avviso, ci sono ottime opportunità di design per il miglioramento progressivo. Analizza le sottigliezze del carattere di sistema, se vuoi.

wght

Accetta uno spessore carattere compreso tra 0 e 900 e viene applicato allo stesso modo a tutti i caratteri.

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

opsz

Il dimensionamento ottico è simile alla crenatura o alla spaziatura tra le lettere, ma la spaziatura viene eseguita da un occhio umano e non da un calcolo matematico. Un valore pari o inferiore a 19 è destinato allo spazio tra il testo e il corpo, mentre un valore pari o superiore a 20 è destinato allo spazio tra intestazioni e titoli.

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

GRAD

Simile a spessore, ma senza modificare la spaziatura orizzontale. Accetta valori compresi tra 400 e 1000.

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

YAXS

Allunga il glifo verticalmente. Accetta valori compresi tra 400 e 1000.

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

Combinare le opzioni

Con poche righe di CSS, possiamo modificare le impostazioni dei caratteri in un grassetto a nostra scelta o provare altre combinazioni interessanti:

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

In men che non si dica, gli utenti di Chromium su macOS vedono il tuo peso di 750 personalizzato aggiornato, con qualche altra divertente modifica 👍

Parco giochi

Fai clic su Remixa per modificare nel glitch qui sotto per ottenere una copia modificabile del glitch, quindi modifica le nuove opzioni font-variation-settings per vedere come influisce sul carattere. Ricorda che questo Glitch funziona solo se utilizzi un dispositivo macOS Catalina.

macOS 10.15 ha aggiunto nuove funzionalità al carattere di sistema e in macOS 10.15 è stato registrato un bug system-ui complicato nel tracker dei bug di Chromium. Mi chiedo se siano correlate?!

Appendice: la regressione system-ui

Questa storia inizia con un bug diverso: #1005969. Questo problema è stato segnalato rispetto a macOS 10.15 perché la spaziatura dei caratteri system-ui sembrava stretta e piena.

Un confronto tra due paragrafi di una pagina di gruppo di Facebook. A sinistra c'è Chrome e a destra Safari. Chrome ha uno spazio leggermente più stretto, ma impercettibile
Chrome a sinistra (monitoraggio più accurato), Safari a destra (spaziatura ottica migliore)

Sfondo

Su macOS 10.14 hai mai notato che i paragrafi o le intestazioni "passavano" a un carattere diverso quando le dimensioni aumentavano o diminuivano?

Su Mojave (macOS 10.14), il carattere system-ui passava da un carattere all'altro a seconda delle dimensioni del carattere target. Quando il testo era inferiore a 20px, macOS ha usato "San Francisco Text". Quando il testo era pari o superiore a 20px, macOS utilizzava "San Francisco Display". Le dimensioni ottiche sono state create in modo statico in due caratteri distinti.

Catalina (macOS 10.15) ha rilasciato un nuovo carattere variabile unito per San Francisco. Non dovrai più gestire "Testo" e "Display". Inoltre, ha acquisito la nuova impostazione della variante opsz descritta in precedenza.

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

Purtroppo, il valore predefinito di opsz nel nuovo carattere Catalina è 20 e gli ingegneri di Chromium non erano preparati ad applicare opsz al carattere di sistema. Di conseguenza, le dimensioni più piccole risultavano troppo strette.

Per risolvere il problema, Chromium doveva applicare opsz correttamente al carattere di sistema. Di conseguenza, il problema 1005969 è stato risolto. Vittoria! O era…?

Non ancora completato

Ecco un problema: Chromium ha applicato opsz, ma qualcosa non sembrava ancora funzionare. I caratteri di sistema su Mac hanno una tabella dei caratteri aggiuntiva denominata trak, che modifica la spaziatura orizzontale. Durante la creazione della correzione, i tecnici di Chromium hanno notato che su macOS, quando venivano recuperate le metriche orizzontali da un oggetto CTFontRef, le metriche trak venivano già prese in considerazione nei risultati delle metriche. La libreria di modellazione di Chromium HarfBuzz ha bisogno di metriche in cui i valori trak non sono ancora stati presi in considerazione.

Una visualizzazione di system-ui e di tutte le sue varianti e i relativi spessori dei caratteri in un elenco. Per la metà di questi prodotti non vengono applicate differenze di peso.
A sinistra: spessori in grassetto applicati alle dimensioni dei caratteri fino al 19. A destra: i caratteri da 20 in su perdono lo stile in grassetto

All'interno, Skia (la libreria grafica, non il carattere dello stesso nome) utilizza sia la classe CGFontRef di CoreGraphics sia la classe CTFontRef di CoreText. A causa delle conversioni interne richieste tra questi oggetti (utilizzati per mantenere la compatibilità con le versioni precedenti e accedere alle API necessarie in entrambe le classi), Skia perderebbe le informazioni sul peso in determinate circostanze e i caratteri in grassetto smetterebbero di funzionare. Questo problema è stato monitorato nel Issue #1057654.

Skia deve ancora supportare macOS 10.11 perché Chromium lo supporta ancora. In 10.11 i caratteri "San Francisco Text" e "San Francisco Display" non erano nemmeno caratteri variabili. Si trattava piuttosto di una famiglia di caratteri separati per ogni spessore disponibile. A un certo punto, i relativi ID glifo non erano più sincronizzati tra loro. Pertanto, se Skia esegue la formattazione del testo (la conversione del testo in glifi che possono essere disegnati) con "San Francisco Text", il risultato sarebbe incomprensibile se il testo viene disegnato con "San Francisco Display" e viceversa. E anche se Skia ha chiesto solo una dimensione diversa, macOS potrebbe passare all'altra. Dovrebbe essere possibile utilizzare sempre uno dei caratteri e ridimensionarlo (utilizzando una matrice per aumentarne le dimensioni anziché richiedere una dimensione più grande), ma CoreText ha un problema: non aumenta le dimensioni dei glifi sbix (emoji a colori) (solo verso il basso). È un po' più complicato di così. CoreText sembra effettivamente limitare l'estensione verticale dopo l'applicazione della matrice, il che sembra essere correlato alla mancata possibilità di disegnare emoji con angoli di 45 gradi. In ogni caso, se vuoi che l'emoji venga visualizzata in grande, devi creare una copia del carattere per ottenere una versione grande.

Pertanto, per creare internamente copie di oggetti CTFont di dimensioni diverse, garantendo al contempo l'utilizzo degli stessi dati di carattere sottostanti, Chromium ha estratto il CGFont dal CTFont, quindi ha creato un nuovo CTFont dal CGFont (gli oggetti CGFont sono indipendenti dalle dimensioni, il passaggio magico avviene a livello di CoreText). Ha funzionato perfettamente fino alla versione 10.154. In 10.15 questo viaggio di andata e ritorno ha perso troppe informazioni, causando il problema di peso. Flutter ha notato il problema di peso ed è stata apportata una correzione alternativa al ridimensionamento per creare il nuovo CTFont direttamente dal file CTFont originale, controllando al contempo le dimensioni ottiche direttamente utilizzando un attributo precedente ma non documentato in CoreText. In questo modo, tutto continuerà a funzionare su 10.11 e verranno corretti altri problemi (ad esempio l'impostazione esplicita delle dimensioni ottiche sul valore predefinito).

Tuttavia, in questo modo si preserva una maggiore quantità di "magia" di CoreText nel carattere. Uno di questi sembra essere che modifichi ancora gli avanzamenti dei glifi in qualche modo diverso dalla semplice tabella trak (la cui applicazione Chromium stava già cercando di eliminare tramite un altro attributo non documentato).

CGFont non esegue nessuna di queste "magie", quindi forse Chromium potrebbe rimuovere CGFont da CTFont e utilizzarlo solo per ricevere gli anticipi? Purtroppo, questo non funzionerebbe perché CoreText è noto per modificare i caratteri anche in altri modi. Ad esempio, rende le emoji piccole leggermente più grandi di quanto hai effettivamente richiesto (aumentandone leggermente le dimensioni). CGFont non sa come funzionano, quindi le emoji basate su sbix saranno troppo vicine tra loro, dato che misureresti con una sola dimensione, ma CoreText le disegneresti di una certa grandezza. Chromium vuole i progressi di CTFont, ma senza il monitoraggio e preferibilmente senza altri problemi.

Poiché la correzione del problema di spaziatura richiedeva una serie di correzioni Blink e Skia interconnesse, i tecnici di Chromium non hanno potuto semplicemente "ripristinare" il problema per risolvere il problema. I tecnici di Chromium hanno anche provato a utilizzare un flag di build diverso per modificare un codepath relativo ai caratteri in Skia, operazione che ha risolto il problema dei caratteri in grassetto, ma ha fatto pregresso il problema di spaziatura.

La correzione

Alla fine, ovviamente, Chromium voleva correggere entrambe le cose. Ora Chromium ricorre alle funzioni di misurazione dei caratteri OpenType integrate in HarfBuzz per recuperare le metriche orizzontali direttamente dai dati binari nelle tabelle dei caratteri del carattere di sistema. In questo modo, Chromium evita CoreText e Skia quando il carattere ha una tabella trak (tranne quando si tratta del carattere emoji).

Una visualizzazione di system-ui e di tutte le sue varianti e i relativi spessori dei caratteri in un elenco. La metà che non funzionava ora funziona perfettamente.

Nel frattempo, c'è ancora Skia Issue n. 10123 per monitorare completamente la correzione di questo problema in Skia e per tornare a utilizzare Skia per recuperare da lì le metriche del carattere di sistema, anziché la correzione corrente che passa attraverso HarfBuzz.