Proč nemůže vlastní externí font fungovat

Pro ozvláštnění stránek je populární používat různá písma – tzv. web fonty.

Většinou ze služeb jako je:

Tyto externí fonty jde buď přímo připojit z uvedených služeb:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">

Nebo si je stáhnout k sobě a provozovat na stejné doméně jako další jiné zdroje (obrázky, styly, skripty).

Zpomalení načítání

Připojování fontů z cizí domény je první technický problém. Jak je vidět na ukázce výš v případě Google Fontů, nejprve se musí stáhnout CSS soubor s deklarací fontů a až následně samotný font.

@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 100;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/roboto/v29/KFOkCnqEu92Fr1MmgVxGIzIXKMnyrYk.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

Z toho plyne, že se proces stažení fontu zbrzdí stahováním dalšího externího CSS, které navíc blokuje vykreslení stránky.

Zvlášť problém je to u pomalého připojení (v DevTools jde nasimulovat volbou Slow 3G), kde to prodlouží první načtení klidně o 2 vteřiny:

CSS font blokuje vykreslení

To je popis situace, kdy se ani dané písmo nepoužívá a nestahuje. Už jen samotné stažení toho CSS má tento negativní dopad – ukázka.

Potom podobnou dobu může zabrat samotné stažení fontu – ukázka

To přináší ještě další risiko v případě výpadku nebo zpomalení dané služby, že bude prohlížeč čekat s vykreslením, až tento styl stáhne.

Kromě toho je potřeba nastavit připojení na další 2 domény, což přináší další režii a zpomalení (trochu to zlepšuje použití <link> značky preconnect).

Roli hraje i velikost samotného souboru s fontem.

K tomu je zase použití služby Google Font dobré, protože CSS vlastností unicode-range rozděluje soubor s písmem na více menších souborů podle potřeby znaků použitých na stránce.

Chybějící české znaky

Snaha ušetřit datovou velikost vede k tomu, že se tvůrce pokusí zahrnout do souboru s písmem pouze znaky, které očekává.

Dost tím trpí zahraniční služby, že nepočítají s češtinou – třeba Tinder:

Tinder chybějící čeština

Tento problém zrovna dobře řeší Google Fonts, kdy všechny znaky rozděluje do souborů a připojuje na základě znaků na stránce pomocí unicode-range.

Blokování textu

Další risiko u vlastního písma je v blokování textu. Projevuje se to tak, že do doby načtení externího fontu není na stránce nic vidět.

Blokováním zobrazení textu se předchází tomu, aby stránka problikla ze stavu s výchozím písmem do stavu s externím fontem po jeho načtení.

To už naštěstí vyřešila CSS vlastnost font-display. Výchozí chování nových prohlížečů je takové, že se na písmo s vykreslením textu nečeká.

Ve starších prohlížečích to ale může být problém.

Poskakování stránky

Chování odpovídající font-display: swap, kdy se stránka nějak vykreslí a po stažení externího fontu se písmo změní, vede k tomu, že stránka po stažení fontu poskočí.

Důvodem je to, že text je v různých fontech jinak velký:

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Nejen šířka znaků, ale proměnlivá je i jejich výška nebo výška řádkování.

Přizpůsobení fallback fontu

Zlepšit toto nepěkné poskakování jde přizpůsobením fallback fontu finální podobě.

Existují 2 možnosti:

  1. Upravit CSS vlastnosti textu.
  2. Upravit vlastnosti fontu ve @font-face deklaraci.

CSS Font Loading API

První technika je založená na použití Font Loading API.

Úpravami CSS vlastností se rozumí změna vlastností jako font-size, line-height, letter-spacing, word-spacing a podobně.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Příliš žluťoučký kůň úpěl ďábelské ódy.

Prostou úpravou letter-spacingu (mezer mezi písmeny) se zde dosáhlo toho, že všechny odstavce jsou přibližně stejně široké, ačkoliv je každý jiným fontem.

Výhoda je v tom, že tohle řešení funguje všude, nevýhoda, že se musí sledovat načítání fontu JavaScriptem:

var font = new FontFace("Vlastní písmo", "url(/fonts/vlastni-pismo.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

font.load().then(function() {
  document.fonts.add(font);
  document.body.classList.remove("font-fallback");
  document.body.classList.add("font-loaded");
});

Tento kód po načtení fontu přidá elementu <body> třídu font-loaded a naopak odebere font-fallback. Ve stylech se na to tak může zareagovat a pro font-fallback upravit záložní písmo tak, aby co nejvíc prostorově odpovídalo vlastnímu externímu písmu.

Užitečný nástroj pro použití této techniky je Font style matcher.

Font style matcher

Jde si tam hezky pohrát s jednotlivými vlastnostmi, aby se oba fonty jakž takž překrývaly:

Překryv fontů

Font display modifikátory

Novější způsob jsou tzv. font display modifikátory. Někdy známé také jako @font-face descriptors, lze se setkat i se zkratkou f-mods.

Vypadá to nějak takto:

@font-face {
    font-family: "Roboto-fallback";
    size-adjust: 100.06%;
    ascent-override: 96%;
    src: local("Arial");
}

Ještě existují vlastnosti descent-override a line-gap-override.

Funguje to mimo Safari a Internet Explorer.

Tím se na základě systémového písma (src: local("Arial")) založí nové písmo s upravenými hodnotami, aby vypadalo podobně jako externí font.

Použití je potom typické:

body {
  font-family: Roboto, 'Roboto-fallback', sans-serif;
}

Výsledkem je trochu méně poskakování – ukázka.

Existuje nástroj Automatic font matching, který dokáže k některým fontům tyto vlastnosti stanovit automaticky.

Případně si to jde nastavit ručně a zkontrolovat, že se obě písma přibližně překrývají – ukázka.

Bohužel to je pořád jen zmírnění dopadů než opravdové vyřešení problému.

Kvůli tomu, že písma používají kerning (vyrovnávání mezer mezi písmeny), který se mezi písmy liší, je podle mě nemožné docílit na pixel přesných rozměrů napříč fonty.

Kerning

Takže 100% za všech případů se poskakování podle mě nedá zabránit.

Systémová písma

Kvůli mnoha problémům a některým neřešitelným s externími fonty může být východisko používat systémová písma.

V roce 2025 třeba v podobě:

body {
    font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'
}

Ukázka

Pro aktuální styl se doporučuji podívat třeba na Tailwind.

Tímto se vzhled stránky přizpůsobí písmu, které používá daný operační systém.

Hodně webů se touto cestou vydává – Facebook, Instagram, GitHub nebo StackOverflow.

Je potřeba si zvážit, zda stojí za to řešit spousty problémů s externími fonty, ze kterých některé ani nemají řešení, nebo použít 100% funkční a načítání nezdružující systémový font.

Na druhou stranu ale volba systémového vzhledu znamená různé zobrazení na různých zařízeních. Je potřeba si rozhodnout, jestli dát přednost rychlému načítání nebo jednotné visuální identitě.

Odkazy jinam

To je všechno. Líbil se vám článek a chcete se dozvědět, až vyjde další?

Sledujte:

 

Připomínky mi pište do komentářů ↓

Česká písma (250 fontů)

Česká písma z Google Fonts

Seznam fontů z Google Fonts, které obsahují znaky s diakritikou pro psaní českého textu.

Seznam českých Google písem – making of

Seznam českých Google písem – making of

Postup, kterým jsou vybírána a určována písma s českou diakritikou z Google Fonts.

Jak zjistit název fontu

Co je to za font?

Jak určit, jak se jmenuje písmo na obrázku nebo webu.

Systémová písma

Systémová písma

Jak a proč používat lokální písma dostupné v operačních systémech.

CSS @font-face

CSS @font-face

Pomocí CSS pravidla @font-face jde na stránce používat různá webová písma.

Komentáře