Spring til indhold

Understregningen der gik gennem bogstaverne

Vores eget site understreger alle links og lader browseren klippe et hul, hvor et bogstavs hale krydser linjen — g‘et, p‘et, kommaet. Det gjorde Safari ikke. Linjen gik lige igennem dem. Sådan havde det været på de engelske og de danske sider, lige så længe sitet havde været flersproget.

Årsagen var tre skrifterklæringer for et alfabet, de sider aldrig henter.

Hvad browseren skal gøre

text-decoration-skip-ink er den egenskab, der løfter en understregning uden om en underlængde. Den er slået til som standard, og i årevis har svaret på “min understregning ser forkert ud” været at gribe fat i text-underline-offset og skubbe linjen længere ned. Det er den forkerte refleks: at flytte linjen ændrer designet, og det, der faktisk manglede, var hullet.

Vi fandt to virkelige årsager, før vi nåede til den interessante, og begge er værd at kende.

  • En understregning på 1px får et hul i størrelsen 1px. Det hul, motoren klipper, står i forhold til tykkelsen på den linje, der klipper det. Vores stylesheet havde låst tykkelsen til én pixel, hvilket efterlod omkring 0,6px luft på hver side af en stamme — teknisk set et hul, visuelt en linje lige gennem bogstavet. text-decoration-thickness: auto skalerede begge dele sammen og tog hullet fra 3,5px til 12,4px uden at flytte understregningen en eneste pixel.
  • from-font er ikke den sikre standard, det lyder som. Den læser den tykkelse, skrifttypen selv angiver, og Ubuntu angiver 0,056em for Light, 0,020em for Medium og 0,120em for Bold — en familie, hvis Medium-linje vejer under halvdelen af dens Light-linje. I store størrelser er det en seks pixel bred linje ved siden af en to pixel bred på samme side.

Det rettede Chrome. Safari trak stadig linjen igennem det hele.

Den del, der tog længst tid

Vi målte det ordentligt: kør et rigtigt Safari, farv understregningen om, tag et skærmbillede i otte gange skala, og tæl de pixels, hvor linjen stopper og starter.

optegnet tykkelsehul omkring en underlængde
Chrome2,00px5,8 / 12,5 / 6,3px
Safari1,38px1,8 / 1,0 / 1,0px

Safari klippede altså et hul. Det var bare seks gange smallere end Chromes, og i læsestørrelse er et hul på én pixel ikke et hul. Værre endnu: det sædvanlige greb gjorde det værre. Ved en tykkelse på 3px faldt Safari fra tre huller til ét, ved 4px til ingen, for den skalerer ikke hullet med linjen. Den låser det til omkring 0,07em i alle størrelser, hvor Chrome giver 0,6em.

Vi afprøvede omkring tyve erklæringer imod den — skip-ink: all, begge de gamle stavemåder af egenskaben, hver tykkelse fra en halv pixel til fire, text-underline-position, font-smoothing, text-rendering, paint-order. Intet gjorde hullet bredere. Den ærlige konklusion på det tidspunkt var, at WebKit ganske enkelt satte et loft over hullet, og at der ikke var mere at gøre fra et stylesheet.

Den konklusion var forkert, og det, der væltede den, var en fejlrapport mod et skriftprojekt: Safari ignorerer skip-ink, når en skrifttype indlæses med et ikke-latinsk udsnit.

Den egentlige årsag

Sitet serverer Ubuntu i seks dele — tre vægte latinsk, tre kyrillisk — så en ukrainsk side sættes i samme skrifttype som en engelsk i stedet for at falde tilbage på det, systemet nu tilbyder. Hver del angiver det tegnområde, den dækker, og browseren henter kun de dele, en side rent faktisk har brug for.

Alle seks var erklæret under det ene familienavn, hvilket er den oplagte måde at skrive det på. Og netop det er udløseren, registreret som WebKit-fejl 255159: når én skrift i en familie angiver et ikke-latinsk tegnområde, forringer Safari skip-ink for hvert eneste tegn i den familie — også latinsk tekst på en side, der aldrig henter den anden fil.

En engelsk side tegnede sine understregninger dårligt, fordi der fandtes en ukrainsk skrifterklæring et sted i stylesheetet. Da vi slettede de tre linjer under kørsel og ikke ændrede andet, gik hullerne fra 1,8/1,0/1,0px til 4,5/11,0/5,0px.

Rettelsen

Giv det andet skriftsystem sit eget familienavn, og nævn det i skriftstakken efter 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;
}

Et latinsk bogstav findes i den første familie og når aldrig den anden. Et kyrillisk falder forbi den første, som ikke har et sådant tegn, og lander i den anden i stedet for i en systemskrift. Tegnområderne bestemmer stadig, hvad der hentes, så intet ved indlæsningen ændrer sig: engelske og danske sider henter tre latinske filer og ingen kyrilliske, ukrainske sider omvendt.

Tre omdøbte erklæringer og én post i stakken. Safaris huller gik til 4,5/11,0/5,0px, Chrome forblev urørt, understregningen flyttede sig ikke, og ukrainsk sættes stadig i Ubuntu i nøjagtig samme bredder.

Hvad vi ville sige til den næste

  • En skip-ink-måling gælder kun for den motor, der frembragte den. Vi havde en tabel med tal, en korrekt diagnose og en virkelig rettelse — og det hele var Chromium. Det skærmbillede, der genåbnede sagen, kom fra et menneske, der kiggede på siden.
  • Grib fat i tykkelsen før forskydningen. At gøre hullet bredere bevarer designet; at flytte linjen ned erstatter det.
  • At dele en skrifttype op efter skriftsystem er rigtigt, men opdelingen hører også hjemme i familienavnet. Ét navn på tværs af skriftsystemer læser bedre og koster dig skip-ink i Safari. At slå dem sammen igen ligner oprydning og er en tilbagegang.
  • Indlæsningen var aldrig problemet. Enhver intuition siger, at en side, der tegner dårligt på grund af en kyrillisk skrift, må hente noget, den ikke burde. Det gjorde den ikke. Erklæringen alene var nok.

Kilder

Det er præcis den slags problemer, vi løser for vores kunder. Kontakt os.

Alle noter