☰ menu
Pavel Satrapa

Počítání v CSS

Občas je třeba některou z hodnot ve stylovém předpisu vypočítat. V jednoduchých případech to zvládneme sami. Je-li prvek široký 50rem, uvnitř jsou dva sloupce a mezi nimi mezera 2rem, je šířka jednoho sloupce (50rem - 2rem)/2, tedy 24rem. A chceme-li mít někde barevný blok zabírající 80 % jeho šířky, bude široký 24rem · 0,8, čili 20rem.

Problém nastane, pokud některý z rozměrů vstupujících do výpočtu není předem známý a bude určen až při zobrazení stránky. Například když celková šířka v předchozím odstavci nebude 50rem, ale stanoví se podle šířky okna prohlížeče. Občas se také ve vzorci kombinuje několik různých jednotek. V takových případech se hodí funkce calc().

calc()

Umožňuje vypočítat hodnotu až během zobrazení stránky na základě aktuálních rozměrů. V našem případě by šířka sloupce byla calc(50% - 1rem). Šířku barevného bloku bych mohl sám ručně vynásobit 0,8 do podoby calc(40% - 0.8rem), ale spíš bych nechal dřinu strojům a použil calc(0.8 * (50% - 1rem)). Ostatně z tohoto vzorce je lépe patrná logika, kterou se k němu došlo.

Funkce calc() se v CSS vyskytuje na místě hodnoty, případně jako její součást, pokud je hodnota složena z několika dílčích hodnot. Má-li být prvek vyšší o 10px než je aktuální velikost písma, bude jeho výška:

height: calc(1em + 10px);

Můžete ji použít tam, kde CSS očekává číslo, procenta, délka, úhel nebo čas.

Pro barvy umožňuje funkce calc() vytvářet různé odstíny a variace. Řekněme, že máme jako základní barvu tmavě červenou definovanou pomocí HSL jako hsl(350, 100%, 30%). Můžeme k ní vytvořit například tmavší variantu snížením světlosti (poslední hodnota) nebo barvu doplňkovou posunutím první hodnoty o 180, tedy polovinu barevného kruhu:

.tmavsi {
    color: hsl(350, 100%, calc(30% / 2));
}

.doplnkova {
    color: hsl(calc(350 + 180), 100%, 30%);
}

V takto jednoduchých případech by jistě bylo efektivnější jednoduché výpočty provést ručně a do CSS zapsat výsledek. Ovšem barvy se často zadávají pomocí proměnných a v takovém případě už použití calc() dává smysl. Mějme proměnné pro jednotlivé barevné složky a pomocí calc() je upravujme:

:root {
    --h: 350;
    --s: 100%;
    --l: 30%;
}

.barva {
    color: hsl(var(--h), var(--s), var(--l));
}

.tmavsi {
    color: hsl(var(--h), var(--s), calc(var(--l) / 2));
}

.doplnkova {
    color: hsl(calc(var(--h) + 180), var(--s), var(--l));
}
.barva
.tmavsi
.doplnkova

Pokud se v některé části stránky proměnné --h, --s nebo --l změní, všechny barvy se odpovídajícím způsobem upraví. Například v následujícím bloku jsem změnil --h na 230, vše ostatní zůstalo:

.barva
.tmavsi
.doplnkova

Všimněte si, že jednotky musí být uvnitř calc(), nikoli mimo. Chcete-li vydělit 30 % dvěma, je třeba psát calc(30% / 2), ne calc(30 / 2)%. Stávající implementace požadují, aby při násobení byla alespoň jedna hodnota bezrozměrná: calc(3 * 50%) je v pořádku, calc(300% * 50%) ne. Při dělení musí být bezrozměrný dělitel, nelze tedy například dělit calc(50% / 2em).

Aritmetické funkce

Většina výpočtů si vystačí se sčítáním (+), odčítáním (-), násobením (*) a dělením (/). Platí obvyklé priority, násobení a dělení má přednost před sčítáním a odčítáním. Pořadí vyhodnocování můžete upravit závorkami, takže 2 + 3 * 4 je 14, zatímco (2 + 3) * 4 je 20.

Pokud byste ale potřebovali něco rafinovanějšího, je k dispozici celá řada aritmetických funkcí:

min(), max() a clamp()

Tato trojice funkcí se používá hlavně při responzivním designu, kdy se vzhled prvků na stránce přizpůsobuje oknu prohlížeče. Například chcete měnit velikosti nadpisů podle šířky okna. Často ale existují určité hraniční hodnoty, přes které nechcete jít, aby nadpis nebyl příliš malý nebo velký.

První dvě funkce jsou nejspíš jasné. Dostanou libovolný počet čárkami oddělených hodnot, ze kterých max() vybere tu největší, zatímco min() tu nejmenší. Uvnitř nich můžete pro hodnoty používat stejné vzorce jako v calc(). Vzorec se vyhodnotí a do porovnání vstoupí výsledná hodnota. Například následující pravidlo přiřadí nadpisu <h1> menší z hodnot 1rem + 3 % šířky okna a 2.5rem:

h1 {
    font-size: min(1rem + 3vw, 2.5rem);
}

Je to trochu neintuitivní, ale pokud chcete omezit nějakou hodnotu shora, tedy stanovit její maximální hodnotu, je třeba použít min(). V našem konkrétním příkladu je první z hodnot proměnlivá a závisí na aktuální šířce okna. Při užším okně bude menší, proto bude výsledkem funkce min() ona. Od určité šířky okna se ale stane větší než 2.5rem, ve funkci min() začne vyhrávat druhá z hodnot a velikost dál neporoste. Vyzkoušejte si to.

Analogicky to platí i na druhou stranu. Chcete-li mít jistotu, že určitá hodnota neklesne pod nějaké minimum, musíte použít max().

Často chcete nastavit obě hranice, jak minimální, tak maximální přípustnou hodnotu. K tomu slouží funkce clamp(). Dostane tři čárkami oddělení hodnoty. První představuje minimum, pod které výsledek nesmí klesnout, druhá je optimální, obvykle bývá závislá na velikosti okna prohlížeče, a poslední je maximální možnou hodnotou. Příklad najdete na konci stránky o responzivním designu.