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

Logické porovnávací funkce 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é.

Umožňují porovnat dvě a více hodnoty:

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).

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

Funkce min()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 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.

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ě ([klæmp]) 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);
}
CSS funkce clamp()

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 méně široký 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.

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

Krása univerzálnosti

Pojďme to ale rozebrat dále, protože to nakonec bude užitečné. V našem případě by zápis vypadal takto:

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

Následuje adekvátní zápis, který pomůže i nám, kterým zanořené matematické funkce působí pupínky.

Jak už jste vy zkušenější jistě pochopili, zápis 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ší. Podstatnější je ale druhý důvod - je univerzální. Je použití není limitované na délkové vlastnosti widthheight. K tomu se ještě musíme vrátit.

Demo: vizualizace výběru funkce

První 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í. Jen si zkuste hýbat se šířkou viewportu:

Demo: ideální šířka textu

V demonstraci u článku o porovnávacích funkcích na web.dev má autorka tento pěkný příklad.

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ů“. 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. Jednotka ch 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);
}

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 se funkcí clamp().

K tomu asi není potřeba nic dalšího dodat. Snad jen to, že autorka nás nabádá, abychom si přitom 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

Komentáře

Váš názor? Vaše zkušenosti? Našli jste chybu?