Martin Michálek Martin Michálek  – 2. 8. 2016

Funkce calc() v CSS umožňuje vložit matematický výraz namísto hodnoty vlastnosti.

Je velmi dobře podporovaná. Je užitečná. Je škoda, že ji kodérky a kodéři nepoužívají častěji. Pojďme to zkusit zlepšit. Nejprve si ukažme dvě jednoduchá využití:

.box {
  width: calc(100% / 3);
}

Rozdělení šířky na tři díly byste asi zvládli i bez kalkulačky, ale výhoda zápisu s calc() je v tom, že nedojde k zaokrouhlení z vaší strany.

.box {
  margin-bottom: calc(1em - 2px); 
}

Něco takového je velmi užitečné. Například když z odsazení nebo šířky elementu potřebujete odečíst šířku rámečku (border).

Není to stejné jako matematika v preprocesorech?

Prosím nezaměňujte calc() s výpočty v CSS preprocesorech jako je Sass. V preprocesoru se musíme spokojit s výrazy, které se mohou zkompilovat do CSS ještě předtím, než prohlížeč stránku vidí:

.box {
  width: (100% / 3)
  // › width: 33.33333333%
}

Jenže preprocesoru dochází dech v momentě, kdy potřebuji kombinovat více jednotek. Vezměme příklad třísloupcového rozvržení s vnějším okrajem o šířce 1em:

.box {
  width: calc(100% / 3 - (2 * 1em))
}

Tady je vidět síla funkce calc(). Počítá se v prohlížeči a jedině prohlížeč zná konkrétní hodnoty, které zastupují jednotky jako je em.

Že se vám to někdy hodilo? Že to obcházíte podivnými hacky? Vítejte v klubu!

Příklady použití

Pojďme si teď více ukázat možnosti praktického využití na vašich projektech.

1) Ukaž matiku!

Nejprve si více rozebereme příklad podobný tomu v úvodu:

.box {
  width: calc(100% / 7);
}

Proč nenapsat rovnou width: 14.2857? Ze dvou důvodů:

  1. Čitelnost kódu. Vsaďte se, že na původ čísla 14,2857 zapomenete. Nejpozději za týden. Správa této části kódu pro vás pak bude znamenat kladení otázek „jak jsem k tomu číslu došel?“. Vždy je lepší zapsat výpočet než výsledek.
  2. Zaokrouhlování. V celé kráse vypadá takto: 14,285714286. Kodéři občas podlehnou pokušení a desetinná místa zaokrouhlí. A pak se diví, že se jim v nějakém konkrétním rozlišení a prohlížeči rozpadlo rozvržení stránky. Nebuďte takoví kodéři. Nezaokrouhlujte.

2) Responzivní obrázky

V parametru sizes značky <img> se bez calc() nedá obejít. Zkuste si bez téhle prima funkce spočítat šířku obrázku uvnitř layoutu, který v responzivním layoutu splňuje následující podmínky:

  1. Na větších displejích zabírá polovinu šířky layoutu stránky. Ale bez vnějších okrajů layoutu (10 pixelů) a samotné stránky (15 pixelů).
  2. Na menších zabírá celou šířku viewportu bez vnějších okrajů stránky (15 pixelů).
<img
  sizes="calc((100vw - 2 * 15px) / 2) - 10px), 
         calc(100vw - 2 * 15px)"   
>

Uznávám, že už je to vypadá docela složitě. Ale bez calc() byste layout stránky pro potřebu responzivních obrázků nedokázali popsat.

(Pro zájemce: více o atributu sizes najdete na Vzhůru dolů. vrdl.cz/p/srcset-sizes)

3) Barevný přechod se stabilně širokou částí

Vezměme gradient, jehož část chceme definovat stabilní šířkou a ostatní části už standardně podílem z celku.

Více řekne obrázek. Černá část bude mít stabilní šířku. Bílá plocha se zmenšuje a zvětšuje podle dostupného místa.

CSS funkce calc() na gradientu

Takto vypadá kód:

div {
  background: 
    linear-gradient(to right bottom, 
      transparent calc(50% - 2em), 
      #000 0, 
      #000 calc(50% + 2em), 
      transparent 0);
}

Následuje živá ukázka z pera Any Tudor.

Ne všechno, co se třpytí, je calc(). Pojďme se teď podívat na příklady užití, které doporučují různé články na webu a které je lepší řešit jinak.

Podpora v prohlížečích

Funkci calc() podporují všechny moderní prohlížeče.

Na CanIUse si můžete přečíst, v jakých situacích tuto užitečnou funkci nepodporuje Internet Explorer 11. Pochybuji, že by se vám doho chtělo. Je to dlouhý seznam. caniuse.com/calc