Understrekingen som krysset hver bokstav
Vårt eget nettsted understreker hver lenke og lar nettleseren skjære ut et
mellomrom der halen på en bokstav krysser linjen — g, p, kommaet. I Safari
gjorde den ikke det. Linjen gikk rett gjennom dem. Slik hadde det vært på de
engelske og danske sidene så lenge nettstedet hadde vært
flerspråklig.
Årsaken var tre fontdeklarasjoner for et alfabet de sidene aldri laster ned.
Hva nettleseren skal gjøre
text-decoration-skip-ink er egenskapen som løfter en understreking unna en
underlengde. Den er slått på som standard, og i årevis har svaret på
«understrekingen min ser feil ut» vært å gripe til text-underline-offset og
skyve linjen lenger ned. Det er feil refleks: å flytte linjen endrer designet,
og det var mellomrommet som faktisk manglet.
Vi fant to reelle årsaker før den interessante, og begge er verdt å kjenne til.
- En
1px-understreking får et mellomrom i1px-størrelse. Bruddet motoren skjærer ut, står i forhold til tykkelsen på selve linjen. Stilarket vårt låste tykkelsen til én piksel, noe som ga rundt 0,6px luft på hver side av en stamme — teknisk sett et mellomrom, visuelt en linje rett gjennom bokstaven. Å settetext-decoration-thickness: autoskalerte begge sammen og tok mellomrommet fra 3,5px til 12,4px uten å flytte understrekingen en eneste piksel. from-fonter ikke det trygge standardvalget det høres ut som. Det leser tykkelsen skrifttypen selv oppgir, og Ubuntu oppgir 0,056em for Light, 0,020em for Medium og 0,120em for Bold — en familie der Medium-linjen er under halvparten så kraftig som Light-linjen. I store størrelser blir det en linje på seks piksler ved siden av en på to piksler på samme side.
Det løste Chrome. Safari trakk fortsatt linjen gjennom alt.
Den delen som tok lengst tid
Vi målte det ordentlig: styrte en ekte Safari, farget understrekingen om, tok skjermbilder i åttedobbel skala og telte pikslene der linjen stopper og starter.
| tegnet tykkelse | mellomrom rundt en underlengde | |
|---|---|---|
| Chrome | 2,00px | 5,8 / 12,5 / 6,3px |
| Safari | 1,38px | 1,8 / 1,0 / 1,0px |
Safari skar altså ut et mellomrom. Det var bare seks ganger smalere enn Chromes, og i lesestørrelse er et mellomrom på én piksel ikke noe mellomrom. Det vanlige grepet gjorde det dessuten verre: med 3px tykkelse gikk Safari fra tre mellomrom til ett, med 4px til ingen, fordi den ikke skalerer mellomrommet med linjen. Den låser det til omtrent 0,07em i alle størrelser, der Chrome gir 0,6em.
Vi prøvde rundt tjue deklarasjoner mot det — skip-ink: all, begge de eldre
skrivemåtene av egenskapen, hver tykkelse fra en halv piksel til fire,
text-underline-position, font-smoothing, text-rendering, paint-order.
Ingenting gjorde det bredere. Den ærlige konklusjonen på det tidspunktet var at
WebKit rett og slett satte et tak på mellomrommet, og at det ikke var mer å
gjøre fra et stilark.
Den konklusjonen var feil, og det som veltet den, var en feilrapport mot et fontprosjekt: Safari ignorerer skip-ink når en skrifttype lastes med et ikke-latinsk delsett.
Den egentlige årsaken
Nettstedet leverer Ubuntu i seks deler — tre vekter latinsk, tre kyrillisk — slik at en ukrainsk side settes i samme skrifttype som en engelsk i stedet for å falle tilbake på det systemet tilbyr. Hver del oppgir hvilket tegnområde den dekker, og nettleseren laster bare ned de delene en side faktisk trenger.
Alle seks var deklarert under det ene familienavnet, som er den opplagte måten å skrive det på. Og nettopp det er utløseren, registrert som WebKit-feil 255159: når ett snitt i en familie oppgir et ikke-latinsk tegnområde, svekker Safari skip-ink for hvert tegn i den familien — også latinsk tekst på en side som aldri henter den andre filen.
En engelsk side tegnet understrekingene sine dårlig fordi en ukrainsk fontdeklarasjon fantes et sted i stilarket. Å slette de tre linjene under kjøring, uten å endre noe annet, tok mellomrommene fra 1,8/1,0/1,0px til 4,5/11,0/5,0px.
Løsningen
Gi det andre skriftsystemet sitt eget familienavn, og nevn det i fontstakken etter det første:
@font-face {
font-family: UbuntuCyrillic; /* var: Ubuntu */
src: url(ubuntu_300_cyrillic.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491;
}
:root {
--body-font: Ubuntu, UbuntuCyrillic, system-ui, sans-serif;
}
En latinsk bokstav finnes i den første familien og når aldri den andre. En kyrillisk faller forbi den første, som ikke har en slik glyf, og havner i den andre i stedet for i en systemskrift. Tegnområdene bestemmer fortsatt hva som lastes ned, så ingenting ved innlastingen endres: engelske og danske sider henter tre latinske filer og ingen kyrilliske, ukrainske sider det motsatte.
Tre omdøpte deklarasjoner og én oppføring i stakken. Mellomrommene i Safari gikk til 4,5/11,0/5,0px, Chrome ble ikke berørt, understrekingen flyttet seg ikke, og ukrainsk settes fortsatt i Ubuntu med identiske bredder.
Det vi ville sagt til den neste
- En skip-ink-måling gjelder bare for motoren som laget den. Vi hadde en tabell med tall, en riktig diagnose og en reell løsning, og alt sammen var Chromium. Skjermbildet som gjenåpnet saken, kom fra et menneske som så på siden.
- Grip til tykkelsen før forskyvningen. Å gjøre mellomrommet bredere beholder designet; å flytte linjen ned erstatter det.
- Å dele en skrifttype etter skriftsystem er riktig, men delingen hører hjemme i familienavnet også. Ett felles navn på tvers av skriftsystemer leses penere og koster deg skip-ink i Safari. Å slå dem sammen igjen ser ut som opprydding og er en regresjon.
- Innlastingen var aldri problemet. Hvert instinkt sier at en side som tegnes dårlig på grunn av en kyrillisk font, må laste ned noe den ikke skal. Det gjorde den ikke. Deklarasjonen alene var nok.
Kilder
Det er nettopp den slags problemer vi løser opp i for kunder. Ta kontakt.