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

Catalina porta su macOS un nuovo carattere di sistema a variabile unita.

Dominik Röttsches
Dominik Röttsches

La sezione "system-ui" delle specifiche del modulo Caratteri CSS di livello 4 definisce una parola chiave per il carattere system-ui che consente agli sviluppatori di utilizzare nei propri siti e nelle proprie app il carattere predefinito del sistema operativo integrato, ottimizzato per il turbo, localizzato, di altissima qualità, senza necessità di download.

body {
  font-family: system-ui;
}

Questa scelta tipografica è simile all'opzione "Utilizza 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 progettazione ha esaminato, testato e... recentemente aggiornato. Prima tratteremo le nuove interessanti funzionalità dei caratteri variabili in Catalina, poi tratteremo un paio di bug e come gli ingegneri di Chromium li hanno risolti.

Questo post presuppone che tu conosca già i caratteri variabili. In caso contrario, consulta l'articolo Introduzione ai caratteri variabili sul Web e guarda il video riportato di seguito.

Compatibilità del browser

Al momento, system-ui supporta Chromium (dal 56), Edge (dal 79), Safari (da 11) e Firefox (da 43), ma con la parola chiave -apple-system. Per gli aggiornamenti, consulta Posso utilizzare i caratteri variabili?.

Nuovi poteri

Le nuove funzionalità che Catalina ha aggiunto al carattere di sistema sono ora disponibili per gli sviluppatori web a partire da Chromium 83. Il carattere system-ui ora ha impostazioni più variabili: dimensionamento ottico e due aggiustamenti specifici del peso:

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 impostazioni wght. Mentre system-ui su Catalina è un carattere variabile con impostazioni wght, opsz, GRAD e YAXS.

Mi sembra di avere delle straordinarie opportunità di progettazione di miglioramenti progressivi. Se vuoi, approfondisci le sfumature del carattere di sistema.

wght

Accetta uno spessore del carattere compreso tra 0 e 900 e viene applicato in modo uniforme 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 anziché da un calcolo matematico. Un valore pari o superiore a 19 si riferisce alla spaziatura di testo e corpo del testo, mentre un valore pari o superiore a 20 si riferisce alla spaziatura tra intestazioni e titoli di visualizzazione.

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

GRAD

Simile al peso, ma senza toccare la spaziatura orizzontale. Accetta valori compresi tra 400 e 1000.

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

YAXS

Allunga il glifo in verticale. 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 o provare altre combinazioni interessanti:

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

E in un attimo, gli utenti di Chromium su macOS vedono il tuo peso 750 personalizzato aggiornato con qualche altra divertente modifica 👍

Parco giochi

Fai clic su Remix per modificare nel Glitch qui sotto per ottenere una copia modificabile, poi modifica le nuove opzioni font-variation-settings per vedere come influisce sul tuo 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 un bug system-ui complicato è stato registrato nel tracker dei bug di Chromium. Mi chiedo se sono correlati!?

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 ristretta e piena.

Un confronto tra due paragrafi da una pagina di gruppo di Facebook. A sinistra c'è Chrome, a destra Safari e Chrome è sottile, ma leggermente più stretto nella spaziatura
Chrome a sinistra (tracciamento più stretto), Safari a destra (spaziatura ottica migliore)

Contesto

Hai mai notato su macOS 10.14 come i paragrafi o le intestazioni "si agganciassero" 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 di destinazione. Quando il testo era in 20px, macOS utilizzava "San Francisco Text". Quando il testo era 20px o superiore, macOS utilizzava "Display di San Francisco". Il dimensionamento ottico è stato incorporato in modo statico in due caratteri separati.

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

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

Purtroppo, il valore predefinito di opsz nel nuovo carattere Catalina è 20 e i tecnici di Chromium non erano pronti ad applicare opsz al carattere di sistema. Di conseguenza, le dimensioni più piccole venivano visualizzate troppo strette.

Per risolvere il problema, Chromium ha dovuto applicare correttamente opsz al carattere di sistema. Di conseguenza, è stato risolto il problema n. 1005969. Vittoria! O no?

Non ancora completato

Ecco dove si è verificato il problema: Chromium ha applicato opsz ma qualcosa non sembrava immobile. I caratteri di sistema su Mac hanno una tabella di caratteri aggiuntiva denominata trak, che modifica la spaziatura orizzontale. Mentre lavoravano alla correzione, gli ingegneri di Chromium hanno notato che su macOS, quando recuperavano le metriche orizzontali da un oggetto CTFontRef, le metriche trak venivano già prese in considerazione nei risultati delle metriche. La libreria shaping di Chromium HarfBuzz richiede metriche in cui i valori trak non sono ancora presi in considerazione.

Una visualizzazione dell'interfaccia utente di sistema con il relativo spessore del carattere e le relative variazioni in un elenco. A metà di essi non vengono applicate differenze di peso.
A sinistra: spessori del grassetto applicati alle dimensioni dei caratteri 19 e inferiori. A destra: le dimensioni dei caratteri a partire da 20 perdono lo stile in grassetto

Internamente, Skia (la libreria grafica, non il tipo di carattere con lo 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 su entrambe le classi), Skia perderebbe le informazioni sul peso in determinate circostanze e i caratteri in grassetto smetteranno di funzionare. Abbiamo monitorato il problema nel numero 1057654.

Skia deve ancora supportare macOS 10.11 perché Chromium lo supporta ancora. Il 10 dicembre, i caratteri di "Testo di San Francisco" e "Display di San Francisco" non erano nemmeno caratteri variabili. Piuttosto, ognuna era una famiglia di caratteri separati per ogni spessore disponibile. A un certo punto, i loro ID glifo sono diventati non sincronizzati tra loro. Ad esempio, se Skia applicasse il formato del testo (convertindo il testo in glifi che possono essere disegnati) con "San Francisco Text", il risultato sarebbe senza senso se disegnato con "San Francisco Display" e viceversa. E anche se Skia ha appena chiesto una dimensione diversa, macOS potrebbe passare all'altra. Dovrebbe essere possibile utilizzare sempre uno dei caratteri e semplicemente ridimensionarlo (utilizzando una matrice per ingrandirlo invece di chiedere una dimensione più grande), ma CoreText ha un problema per cui i glifi sbix (emoji colori) non vengono ridimensionati verso l'alto (solo verso il basso). È un po' più complesso. CoreText sembra in realtà limitare l'estensione verticale dopo l'applicazione della matrice, il che sembra essere correlato al fatto che non è in grado di disegnare emoji a angoli di 45 gradi. In ogni caso, se vuoi che la tua emoji venga visualizzata in grandi dimensioni, devi creare una copia del carattere per ottenere una versione grande.

Di conseguenza, per creare internamente copie di oggetti CTFont di dimensioni diverse, garantendo al contempo che vengano utilizzati gli stessi dati dei caratteri sottostanti, Chromium ha estratto CGFont da CTFont, quindi ha creato un nuovo CTFont da CGFont (gli oggetti CGFont sono indipendenti dalle dimensioni, il cambio magico avviene a livello CoreText). Questo ha funzionato bene fino al 10.154. In 10:15 questo round trip alla fine ha perso troppe informazioni, con un conseguente problema di peso. Flutter ha notato il problema di peso ed è stata apportata una correzione alternativa per il ridimensionamento in modo da creare il nuovo CTFont direttamente dall'originale CTFont, controllando direttamente le dimensioni ottiche utilizzando un attributo vecchio ma non documentato in CoreText. Questo consente di continuare a funzionare sulla versione 10.11 e di risolvere altri problemi (ad esempio l'impostazione esplicita delle dimensioni ottiche sul valore predefinito).

Tuttavia, in questo modo viene conservata una maggiore parte della "magia" di CoreText nel carattere. Uno di questi sembra essere che modifica ancora i progressi del glifo in un modo diverso dalla tabella trak (la cui applicazione Chromium stava già cercando di eliminare tramite un altro attributo non documentato).

CGFont non è in grado di svolgere questa "magia", quindi forse Chromium potrebbe ottenere lo sconto di CGFont su CTFont e usarlo solo per ottenere progressi? Purtroppo questa operazione non funzionerebbe perché è noto che CoreText non utilizza i caratteri anche in altri modi. Ad esempio, in questo modo le emoji sono leggermente più grandi di quelle da te richieste (aumentando leggermente le dimensioni). CGFont non sa nulla di questo, quindi finiresti con le emoji basate su sbix troppo vicine tra loro perché misureresti a una dimensione, ma CoreText le disegnerebbe più velocemente. Chromium vuole che CTFont avanza, ma li vuole senza monitoraggio e preferibilmente senza dover fare nulla.

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

Soluzione

Alla fine, ovviamente, Chromium voleva risolvere entrambi i problemi. Chromium ora ricorre all'utilizzo delle funzioni delle metriche dei caratteri OpenType per i caratteri integrati HarfBuzz per recuperare metriche orizzontali direttamente dai dati binari nelle tabelle dei caratteri del carattere di sistema. Usando questo sistema, Chromium sta eludendo CoreText e Skia quando il carattere ha una tabella trak (tranne nel caso del carattere dell'emoji).

Una visualizzazione dell'interfaccia utente di sistema con il relativo spessore del carattere e le relative variazioni in un elenco. La metà che prima non funzionava ora sembra funzionare al meglio.

Nel frattempo esiste ancora il Numero di Sci n. 10123 per tracciare la correzione di questo problema in Skia e tornare a utilizzare Skia per recuperare da lì le metriche dei caratteri di sistema, anziché la correzione attuale che passa attraverso HarfBuzz.