# Understrekingen som krysset hver bokstav

2026-09-28

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 *(feilen ingen melder: den ser bare billig ut)*.

Å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 i `1px`-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. Å sette `text-decoration-thickness: auto` skalerte begge sammen og
  tok mellomrommet fra 3,5px til 12,4px uten å flytte understrekingen en eneste
  piksel.
- **`from-font` er 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](https://github.com/fontsource/fontsource/issues/1096):
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](https://bugs.webkit.org/show_bug.cgi?id=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:

```css
@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

- [WebKit-feil 255159 — `text-decoration-skip-ink` og delsett av fonter](https://bugs.webkit.org/show_bug.cgi?id=255159)
- [Fontsource-sak 1096, som pekte ut utløseren](https://github.com/fontsource/fontsource/issues/1096)
- [MDN: `text-decoration-skip-ink`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-skip-ink)
- [MDN: `unicode-range`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range)

<https://software.engineer.company/nb/notes/safari-underline-font-subset/>
