Někdo se snažil vyjmenovávat hromadu rodin, snad některá bude k dispozici, jiný rezignoval a omezil se na obecné serif/sans-serif. Reálně se nedalo předvídat, jaké písmo prohlížeč použije. To je ovšem obecný princip webu. Prohlížeče a prostředí uživatelů jsou rozmanité a každý vidí stránku trochu jinak.
S příchodem webových písem dostali autoři pod kontrolu alespoň ta písma. Soubor s písmem se dá umístit na web, prohlížeč si jej stáhne a použije pro zobrazení stránky. Slouží k tomu deklarace @font-face
. Obsahuje vlastnosti popisující parametry písma ( font-family
, font-weight
, font-style
, font-stretch
a podobně) a důležitou vlastnost src
odkazující na zdroj písma. Jejich význam je „písmo s těmito parametry najdeš tady“. Například deklarace
@font-face { font-family: Inter; font-style: normal; font-weight: normal; src: url(/fonts/Inter-Regular.woff2); } @font-face { font-family: Inter; font-style: italic; font-weight: normal; src: url(/fonts/Inter-Italic.woff2); } @font-face { font-family: Inter; font-style: normal; font-weight: bold; src: url(/fonts/Inter-Bold.woff2); } @font-face { font-family: Inter; font-style: italic; font-weight: bold; src: url(/fonts/Inter-BoldItalic.woff2); }
říkají, že základní řez rodiny Inter si má prohlížeč stáhnout v souboru Inter-Regular.woff2, který najde v adresáři fonts, kurzívu v Inter-Italic.woff2, tučný řez v Inter-Bold.woff2 a tučnou kurzívu v Inter-BoldItalic.woff2. Prohlížeč samozřejmě stahuje jen ta písma, která jsou na stránce použita.
Pro variabilní písma se deklarace zjednoduší. Typicky bývá oddělen vzpřímený řez od kurzívy a duktus je řízen variabilní osou. V tom případě vlastnost font-weight
můžete úplně vynechat, nebo v ní uvést rozpětí hodnot, pro něž deklarace platí. Níže vidíte příklady obou přístupů. U vzpřímeného písma jsem duktus vynechal, což považuji za praktičtější, u kurzívy je uvedeno rozpětí:
@font-face { font-family: Inter; font-style: normal; src: url(/fonts/InterVariable-Regular.woff2); } @font-face { font-family: Inter; font-style: italic; font-weight: 100 900; src: url(/fonts/InterVariable-Italic.woff2); }
Základní hodnotou vlastnosti src
je url(
lokátor)
s adresou, na které je písmo ke stažení. Můžete přidat i identifikaci jeho formátu pomocí format(
formát)
, ale je to celkem zbytečné. Zdrojů lze uvést několik, oddělují se čárkami. Funguje to jako obvykle, klient je postupně prochází a použije první, kde uspěje. Díky tomu lze písmo například nabídnout v různých formátech. Upřímně řečeno to nestojí za námahu, protože už delší dobu všechny aktuální prohlížeče podporují formát Web Open Font Format verze 2. Nabízet jiné formáty než WOFF2 má přínos ryze homeopatický.
Zajímavý je ovšem zdroj local(
název)
, který odkazuje na lokálně instalované písmo. Výše uvedené hodnoty src
znamenají, že prohlížeč vždy použije webové písmo bez ohledu na to, zda písmo Inter je v jeho systému k dispozici, nebo ne. Drobnou úpravou
src: local("Inter"), url(/fonts/Inter-Regular.woff2);
bychom dosáhli toho, že se prohlížeč nejprve podívá, zda je v systému instalováno písmo jménem Inter. Pokud ano, použije je. V opačném případě stáhne webové písmo ze zadané adresy.
Chcete to? Písmo se může vyvíjet (například pro Inter existuje už čtvrtá velká verze a řada podverzí) a uživatel může mít instalovánu jinou verzi. Jenže řadu dalších parametrů zobrazení stejně neznáte a neovlivníte, takže trochu odlišná verze písma bude nejspíš zanedbatelná. Proto doporučuji vždy nejprve uvést local()
, aby se použilo místní písmo, pokud existuje, a teprve za ním url()
pro ty, kteří písmo v systému nemají.
Výhodou lokálního písma je to, že se moc nehledí na velikost souboru, takže může obsahovat i znaky, které byly z jeho webové varianty kvůli zmenšení odebrány. Například mé lokálně instalované písmo Roboto samozřejmě zahrnuje kapitálky. Čili kombinace zdroje local()
se zákazem generování font-synthesis: none
může být přijatelnou platformou pro používání kapitálek. Ti, kteří písmo instalováno nemají, budou mít text zobrazen základním řezem, což se dá přežít.
Když prohlížeč stahuje písmo, chvilku to trvá. Během ní může čekat a nezobrazovat nic, jenže to by nemělo trvat moc dlouho. Může také dočasně použít náhradní písmo a po stažení je nahradit tím správným. To ovšem často způsobí překreslení stránky, protože rozměry jednotlivých znaků obou písem se liší, vyjde jinak rozdělení slov do řádků a obsah stránky se může znatelně posunout. Uživatelé a metriky Google to nemají rádi.
Vlastností font-display
uvnitř @font-face
můžete řídit chování prohlížeče během stahování písma. Výchozí hodnota auto
to nechá na něm. Dále jsou k dispozici hodnoty swap
a block
, které obě čekají na stažení písma neomezeně dlouho a až se povede, vykreslí jím text místo dočasně použitého náhradního písma. Liší se délkou úvodního intervalu, kdy se nevykresluje nic a čeká se, zda písmo dorazí, nebo se použije náhradní. swap
má tento interval velmi krátký (doporučeno je 100 ms), block
delší (3 s). CSS Font Module Level 4 od používání těchto dvou silně odrazuje. Podle něj byste je po nich měli sáhnout, jen pokud na daném písmu opravdu hodně záleží ( swap
), nebo je dokonce nezbytné ( block
). Pro hlavní texty doporučuje jednu z následujících dvou hodnot.
fallback
zařídí, že prohlížeč velmi krátkou dobu (100 ms) nezobrazuje nic, pak použije náhradní písmo a chvilku (3 s) čeká na příchod toho správného. Nedorazí-li během ní, už zůstane u náhradního písma, protože pozdní překreslení stránky uživatelům vadí mnohem víc, než když k němu dojde krátce po otevření. A konečně optional
pokud nemá webové písmo k dispozici víceméně hned, použije náhradní a už u něj zůstane. V tomto případě se stránka nepřekresluje nikdy.
Na vlastnosti font-display
reálně záleží jen u první otevřené stránky webu. Když pak uživatel bude následovat odkazy a přecházet na další stránky, písma už bude mít prohlížeč uložena ve vyrovnávací paměti a budou k dispozici hned.
V mimořádných případech se uvnitř @font-face
může hodit vlastnost unicode-range
, kterou omezíte jeho platnost jen na znaky s uvedenými kódy podle Unicode. Dají se tak například převzít vybrané znaky z jiného písma, pokud v původním písmu chybí nebo je od něj chcete odlišit.
Když na stránce kombinujete různá písma, může se stát, že mají různou střední výšku a při stejném stupni vypadají různě velká. Například v následující ukázce je pro základní text použito písmo Alegreya, zatímco pro nápisy uživatelského rozhraní Monserrat. Bez korekce je Montserrat znatelně větší, jak vidíte v prvním odstavci.
Řešení tohoto problému umožňuje vlastnost size-adjust
, kterou vložíte do@font-face
a příslušný řez zmenšíte nebo zvětšíte. Hodnota se zadává v procentech. Pro druhý odstavec jsem do@font-face
písma Monserrat přidal
size-adjust: 85%;
a zmenšil jej tak na 85 % jeho původní velikosti. Tato korekce má globální platnost – kdekoli se písmo vyskytuje a v jakémkoli stupni, vždy bude zmenšeno na 85 % toho, jak by vypadalo bez korekce. Díky tomu bude jeho velikost odpovídat okolnímu písmu Alegreya se stejně nastavenou velikostí.
Když už je řeč o úpravě velikosti, zmíním se ještě o vlastnosti font-size-adjust
. Ta se netýká deklarace @font-face
, ale lze ji používat v běžných pravidlech. Má podobný cíl, tedy upravit velikost písma vůči jeho standardní velikosti. Hodnota se ovšem zadává jinak. Tentokrát se jedná o číslo (typicky z rozsahu od 0 do 1), které udává poměr mezi střední výškou písma, čili výškou minusek, a nastaveným stupněm. Hodnota
font-size-adjust: 0.5;
znamená, že minusky mají být vůči stupni poloviční. Jestliže má například písmo nastavenou velikost 12 b, minusky mají být vysoké 6 b. Prohlížeč porovná střední výšku použitého písma a je-li jiná, písmo zvětší nebo zmenší, aby byly minusky správně velké. Řekněme, že aktuální písmo má poměr minusek ke svému stupni 0,55, takže by při stupni 12 b byly jeho minusky vysoké 6,6 b. Proto písmo zmenší cca o 10 %, aby se s minuskami dostal na cílových 6 b.
Mám-li být upřímný, nenapadá mě žádné praktické využití této vlastnosti. Korekce velikosti jsou zpravidla potřebné kvůli vyladění vzájemného poměru velikostí různých rodin a je logičtější dělat je ve @font-face
pomocí size-adjust
s globálním účinkem na všechny výskyty daného písma.
Ještě se alespoň letmo zmíním o tom, kde vzít písma ve formátu WOFF. Ve skutečnosti je mít ani nemusíte. Cesta v url()
může vést kamkoli, soubor s písmem se klidně může nacházet na jiném serveru. Lze například využít písma nabízená na Google Fonts. Stačí si vybrat písmo, po klepnutí na Get font zvolit variantu Get embed code a zkopírovat vygenerovaný kód do HTML a CSS. Podobně to dělá i root.
Chcete-li si svá písma hostovat sami, najdete formát WOFF často jako součást distribučních balíčků jednotlivých písem. Pokud není obsažen, nebo si jej chcete vytvořit sami a optimalizovat jeho obsah, existuje celá řada generátorů, které jej vytvoří ze standardních formátů OpenType nebo TrueType. Jsou k dispozici jak pro příkazový řádek (např. fontTools), tak s webovým rozhraním (třeba Webfont Generator, který po přepnutí do expertního režimu dovede ledacos).
Právě v optimalizaci spočívá hlavní zádrhel. Autoři písem se snaží své výtvory vyšperkovat a obohatit různými vychytávkami, které ale zvětšují objem dat. Chcete třeba mít v písmu azbuku nebo řečtinu, když víte, že je na svém webu nepoužíváte? Při konverzi do formátu WOFF je proto celkem obvyklé vypustit z písma prvky, jejichž přínos nestojí za nárůst objemu dat. Délky optimalizovaných souborů WOFF se běžně pohybují v desítkách kilobajtů, ale například variabilní Noto Sans má bez optimalizace přes megabajt, což pro web není přijatelné.
Různé typografické speciality, kterým se následně budu věnovat, proto nemusí být dostupné, přestože je původní písmo obsahuje. Často zkrátka padnou za oběť snižování objemu dat. Proto doporučuji hodnotu src
začínat zdrojem local()
, aby si je užili alespoň uživatelé, kteří mají písmo nainstalováno se vším všudy.
Typografické speciality
V seriálu o písmech jsem popisoval řadu typografických jemnůstek, kterými autor může písmo ozvláštnit. Patří sem například různé ligatury, více variant číslic a podobně. Jsou identifikovány čtyřpísmennými zkratkami a pro jejich nastavování je v CSS k dispozici několik specializovaných a jedna univerzální vlastnost.
Začněme tou univerzální: font-feature-settings
umožňuje zapínat a vypínat jednotlivé typografické vychytávky. Pokud jsou v písmu k dispozici… Její hodnotou jsou čárkami oddělované řetězce znaků se zkratkami. Za každou zkratkou může následovat číslo nebo klíčové slovo on
(ekvivalentní číslu 1) nebo off
(ekvivalent 0). Chybí-li číslo, použije se výchozí hodnota 1, tedy vlastnost se zapne.
Řekněme, že v běžném textu chci používat minuskové proporcionální číslice a neobvyklé ligatury. V tabulkách ovšem preferuji verzálkové tabulkové číslice a neobvyklé ligatury vypnu. Zajistil by to následující úryvek CSS:
:root { font-feature-settings: "onum", "pnum", "dlig"; } table { font-feature-settings: "lnum", "tnum", "dlig" off; }
V ideálním případě by se ale vlastnost font-feature-settings
vůbec neměla vyskytovat. Čtyřpísmenné zkratky typografických laskomin nejsou pro nás příliš přívětivé a vyznat se v tom, co konkrétní hodnota vlastně nastavuje, nemusí být snadné. Proto existuje několik specializovaných vlastností pro konkrétní charakteristiky písma a důrazně se doporučuje dávat jim přednost před font-feature-settings
. Projděme si je.
font-variant-ligatures
ovládá ligatury. Dostupné hodnoty jsou:
normal
– výchozí hodnota,none
– vypne,common-ligatures
,no-common-ligatures
– běžné ligatury (liga a clig),discretionary-ligatures
,no-discretionary-ligatures
– neobvyklé ligatury (dlig),historical-ligatures
,no-historical-ligatures
– historické ligatury (hlig),contextual
,no-contextual
– kontextové alternativy (calt).
Lze uvádět i více hodnot, oddělují se mezerami. Například zapnutí neobvyklých a historických ligatur a kontextových alternativ v celé stránce by zajistilo:
:root { font-variant-ligatures: discretionary-ligatures historical-ligatures contextual; }
font-variant-numeric
vybírá číslice, které se mají používat. Máme k dispozici hodnoty:
normal
– výchozí hodnota, podle písma,lining-nums
– verzálkové (lnum),oldstyle-nums
– minuskové (onum),tabular-nums
– tabulkové (tnum),proportional-nums
– proporcionální (pnum),slashed-zero
– používat přeškrtnutou nulu (zero),ordinal
– používat speciální znaky pro anglické řadové číslovky 1st, 2nd a spol. (ordn),diagonal-fractions
– pro zlomky (1/2 apod.) používat znaky s šikmou zlomkovou čarou (frac),stacked-fractions
– pro zlomky (1/2 apod.) používat znaky s vodorovnou zlomkovou čarou (afrc).
Výše uvedený příklad, kdy v běžném textu chci používat minuskové proporcionální číslice a neobvyklé ligatury, v tabulkách ovšem preferuji verzálkové tabulkové číslice a neobvyklé ligatury vypnu, by bylo vhodnější nastavit následovně:
:root { font-variant-numeric: oldstyle-nums proportional-nums; font-variant-ligatures: discretionary-ligatures; } table { font-variant-numeric: lining-nums tabular-nums; font-variant-ligatures: no-discretionary-ligatures; }
Je to sice delší, ale výrazně srozumitelnější.
font-variant-caps
umožňuje zapnout kapitálky. Hodnot pro ni existuje několik, protože v ojedinělých případech může písmo obsahovat více variant kapitálek, ze kterých si můžete vybírat. Reálně si vystačíte se dvěma:
normal
– bez kapitálek,small-caps
– kapitálky.
Řekněme, že chci mít kapitálkami dvě nejvyšší úrovně nadpisů:
h1, h2 { font-variant-caps: small-caps; }
font-variant-alternates
vybírá mezi různými alternativními znaky. Na rozdíl od číslic jsou alternativní tvary jiných znaků celkem vzácné. Najdete je nejčastěji v různých ozdobných písmech a na webu tuto vlastnost nejspíš nebudete potřebovat. Nicméně pro pořádek její hodnoty:
normal
– výchozí hodnota,historical-forms
– historické tvary znaků (hist),stylistic(
identifikátor)
– stylistické alternativy pro jednotlivé znaky (salt),styleset(
identifikátor)
– stylistické alternativy pro skupiny znaků (ssXY),character-variant(
identifikátor)
– varianty znaků (cvXY),swash(
identifikátor)
– ozdobné tvary (swsh, cswh),ornaments(
identifikátor)
– ornamentální a dekorativní znaky (ornm),annotation(
identifikátor)
– doplňky znaků, např. kroužky kolem číslic (nalt).
V hodnotách se často používají identifikátory znaků, jichž se týkají. Mohou být číselné, ale tyto číselné kódy se mění písmo od písma. Pokud by došlo k použití záložního písma, protože se webové nepodařilo načíst, může stejné číslo znamenat úplně jiný symbol. Proto deklarace @font-feature-values
umožňuje definovat pro ně pojmenované identifikátory, jejichž číselná hodnota se dosadí podle použitého písma. Jelikož se jedná o velmi exotickou záležitost, nemá cenu jí věnovat příliš prostoru. V případě zájmu najdete podrobnosti ve specifikaci.
font-variant-position
slouží k přepnutí na variantu písma určenou pro horní nebo dolní index. Písma, s nimiž si jejich autoři vyhráli, obsahují zmenšené varianty znaků pro indexy. Pro web je to ale celkem luxus, protože je třeba zopakovat celou abecedu včetně všech možných akcentů a velikost souboru s písmem znatelně naroste. Proto se obvykle indexy vytvářejí zmenšením a posunutím běžných znaků a specializované znaky se ze souborů WOFF vypouští. Pokud by tam byly, lze je přepínat hodnotami:
normal
– běžné písmo, výchozí hodnota,super
– horní index (sups),sub
– dolní index (subs).
Pro úplnost zmíním ještě vlastnost font-variant-east-asian
, kterou lze vybírat alternativy znaků pro asijské jazyky, jako je japonština nebo čínština. font-variant-emoji
pak řídí, jak se budou zobrazovat emotikony.
Pro všechny zde uvedené vlastnosti existuje souhrnná vlastnost font-variant
, jejíž hodnotu poskládáte z celkem libovolné kombinace hodnot dílčích vlastností font-variant-něco
. Jejich hodnoty se nepřekrývají, takže prohlížeč pozná, co má nastavit. Vzhledem k tomu, že se zpravidla nastavuje jen pár typografických vlastností, je to kratší a dost praktické.
Ještě jedou se vrátím k příkladu s nastavením číslic. Optimální podoba příslušného CSS by byla následující:
:root { font-variant: oldstyle-nums proportional-nums discretionary-ligatures; } table { font-variant: lining-nums tabular-nums no-discretionary-ligatures; }
Některá písma mohou měnit tvar znaků podle velikosti. Můžete jim to zakázat, když vlastnosti font-optical-sizing
přiřadíte hodnotu none
. Výchozí hodnotou je auto
, tedy povoleno. Nenapadá mě vhodný příklad, kdy by bylo k užitku ji měnit.
Do podobného soudku patří vlastnost font-kerning
, která umožňuje vypnout kerning. Ale proč byste to dělali? Nanejvýš stojí za úvahu si dupnout a hodnotou normal
jej vždy požadovat. Výchozí hodnotou je totiž auto
, která ponechává rozhodnutí na klientovi. Nicméně typický klient kerning používá.
(Autorem obrázků je Pavel Satrapa.)