Martin Michálek Martin Michálek  – 10. 8. 2021

Funkce, které se uvádějí místo hodnot v deklaracích stylů, umožňují porovnat dvě a více hodnot:

Funkce Význam
min() Vrací nejmenší hodnotu z argumentů oddělených čárkou.
Např. min(50%, 200px).
max() Vrací největší hodnotu z argumentů oddělených čárkou.
Např. max(50%, 10vw, 200px).
clamp() Vrací prostřední hodnotu, pokud není menší než první a větší než třetí.
Např. clamp(100px, 20%, 200px).

Jsou součástí čtvrté verze specifikace „CSS Values and Units Module“, podporují je všechny moderní prohlížeče a ještě k tomu jsou užitečné.

Funkce min(), max()clamp() nám v CSS prakticky umožní lépe řídit velikost prvků, dodržovat správné mezery mezi prvky nebo třeba implementovat plynulou („fluidní“) typografii.

Jak fungují?

Funkce min() a max()

U funkcí min()max() to je jednoduché – zadáte seznam argumentů a prohlížeč určí, která z hodnot je nejmenší nebo největší.

Související

Příklad:

.box-1 {
  width: min(100px, 50%);
}

Šířka .box-1 bude určena tím menším přepočtem na pixely z obou hodnot. V dostatečně širokém rodičovském prvku to bude většinou 100px, ale v opravdu malých šířkách se může použít 50%, protože vypočtená hodnota šířky bude menší než 100px.

Zkusme si představit totéž pro funkci max():

.box-2 {
  width: max(100px, 50%);
}

Šířka .box-1 bude určena větší pixelovou hodnotou vypočtenou z obou atributů. Jak asi sami tušíte, většinou se použije hodnota 50% a jen na opravdu malých rozlišeních prohlížeč vybere 100px.

V tomto případě jde o obdobu zápisu width:50%;min-width:100px. V ukázce to sami uvidíte.

Funkce clamp()

Jeden z významů slova „clamp“ v angličtině je „svěrka“, což je vcelku přesné. První a poslední atribut v závorce totiž udává minimální a maximální sevření, prostřední je ideální hodnota:

.box-3 {
  width: clamp(100px, 50%, 300px);
}

Vysvětlíme to ještě detailně:

  • Prostřední argument je ideální hodnota. .box-3 bude široký 50%, pokud nevstoupí v platnost svěrka z jedné nebo druhé strany.
  • První argument je minimální hodnota. Prvek nesmí být užší než 100px.
  • Třetí argument je maximální hodnota. .box-3 nebude nikdy širší než 300px.

Je to srozumitelné? Ještě si to případně zkuste na CodePenu.

Následující ukázku jsem si vypůjčil od Uny Kravets. Je to krásná vizualizace, ve které je vidět aktuální šířka rodiče, elementu a pak také argument funkce min(), který je v dané šířce obrazovky aktivní.

Pokud si to budete zkoušet naživo, zkuste si hýbat se šířkou viewportu.

Ve specifikaci se uvádí, že funkci clamp() je možné zapsat pomocí min()max() jako max(MIN, min(VAL, MAX)). Nevím jak vám, ale mně to moc při snaze pochopit funkci clamp() nepomohlo.

Krása univerzálnosti

Pojďme však vzoreček ze specifikace rozebrat více. Nakonec možná dojdeme k tomu, že bude užitečný. V případě výše uvedeného kódu by zápis vypadal takto:

.box-3 {
  width: max(100px, min(50%, 300px));
}

Zopakuji i původní zápis pomocí funkce clamp():

.box-3 {
  width: clamp(100px, 50%, 300px);
}

Jak už jste jistě pochopili, kód výše je stejný, jako bychom napsali následující deklaraci:

.box-3 {
  width: 50%;
  min-width: 100px;
  max-width: 300px;
}

Konstrukce s min-widthmax-width v CSS máme a mnozí známe už od pravěkých dob. Tak proč zavádět nový zápis v podobě funkcí min(), max()clamp()?

Za prvé je nový zápis stručnější a možná přehlednější, nejdůležitější je ale jeho univerzálnost. Použití není limitované na délkové vlastnosti widthheight.

To je tak zajímavé, že to musíme rozebrat. Jen chvíli počkejte.

Demo: ideální šířka textu

Ve známé knize „The Elements of Typographic Style“ od Roberta Bringhursta se píše, že „za uspokojivou délku řádku pro jednosloupcovou stránku s patkovým písmem se obecně považuje 45 až 75 znaků“. vrdl.in/zaosw

Toto můžeme krásně definovat právě pomocí porovnávací funkce:

.card {
  width: clamp(45ch, 50%, 75ch);
}

Prvek .card bude zabírat 50% šířky rodiče, ale nikdy méně než 45ch a více než 75ch. Pokud to nevíte, jednotka ch v sobě obsahuje šířku znaku 0, což se považuje za průměrnou šířku znaku.

Demo: plynulá typografie

V další ukázce Uny Kravets konečně odbočíme mimo vlastnosti určující šířku elementu. Budeme nastavovat maximální a minimální velikost textu a tím plně využijeme nových porovnávacích funkcí.

h1 {
  font-size: clamp(1.5rem, 5vw, 3rem);
}

Velikost písma se bude s rozšiřováním okna zvětšovat od 1.5rem až po 3rem.

Jednotkou vw nastavujeme velikost písma na pět procent šířky viewportu. Abychom se přitom vyhnuli extrémně malým a extrémně velkým hodnotám font-size, pomáháme si funkcí clamp().

Čtenář Dan Srb mi po publikování první verze tohoto textu na Vzhůru dolů poslal ještě jeden tip ke stupňovitému zvětšování písma:

Pokud chcete například zajistit, aby se od pětisetpixelové šířky viewportu začalo písmo zvětšovat z 1rem na 2rem až k hranici šířky viewportu 900px, pak je tu tahle kalkulačka na snadno zapamatovatelné adrese: xgkft.csb.app. (Lze použít např. i pro vlastnost padding.)

Dodejme ještě, že autorka původního CodePenu nás nabádá, abychom si při těchto hrátkách s velikostí písma dávali pozor na přístupnost.

Omezení velikosti textu pomocí funkcí max() nebo clamp() může být proti pravidlům přístupnosti WCAG, která doporučují, aby si uživatelé mohli písmo libovolně zvětšovat sami.

Co byste ještě měli vědět o porovnávacích funkcích?

Funkce min(), max()clamp() mají v DNA pár důležitých vlastností, které se mi jinam nevešly, ale přesto si zaslouží vaši pozornost:

  • Funkce můžete skládat a zanořovat. Např. font-size:max(min(0.5vw,1em),2rem). Není ale garantováno, že vás z toho nerozbolí hlava.
  • Stejně jako funkce calc() umožňují porovnávací funkce používat matematické výrazy se sčítáním (+), odčítáním (-), násobením (*) a dělením (/) jako součástí hodnot. Zápis font-size:max(calc(0.5vw - 1em),2rem) je tudíž stejný jako font-size:max(0.5vw - 1em,2rem).
  • Co když ve funkci clamp() prohodíte minimum a maximum? Vyhraje minimum. Například zápis clamp(100px,…,50px) bude vracet hodnotu 100px, čímž překročí maximum uvedené ve třetím argumentu.

Podpora v prohlížečích

Je to dobré. Funkce min(), max()clamp() podporují všechny moderní prohlížeče. V Internet Exploreru vám tyto funkce neprojdou.

Můžete to ověřit na CanIUse: caniuse.com/css-math-functions