calc()

Wylicza wartość z działania matematycznego i pozwala łączyć różne jednostki, na przykład procenty z pikselami.

Na tej stronie

Przykład

#
CSS
.progress {
  height: 10px;
  border-radius: 999px;
  background: #27272a;
}

.progress-fill {
  width: calc(var(--progress) * 1%);
  height: 100%;
  border-radius: inherit;
  background: #10b981;
}
Podgląd

Szablon strony wpisuje w atrybucie style samą liczbę (--progress: 65), a calc() zamienia ją na szerokość w procentach.

Definicja i zastosowanie

#

Funkcja calc() pozwala wpisać działanie wszędzie tam, gdzie CSS oczekuje liczby, długości, kąta, czasu albo procentu. Obsługuje dodawanie +, odejmowanie -, mnożenie *, dzielenie / i nawiasy. Największa zaleta to mieszanie jednostek: calc(100% - 80px) oznacza „cała szerokość rodzica bez 80 pikseli”, a takiej wartości nie da się policzyć zawczasu, bo szerokość rodzica znana jest dopiero w przeglądarce.

Wokół + i - muszą stać spacje. Bez nich przeglądarka odczyta -80px jako liczbę ujemną i uzna całe wyrażenie za błędne. Przy * i / spacje nie są wymagane, ale poprawiają czytelność. Najprościej mnożyć i dzielić długość przez zwykłą liczbę: calc(10px * 3), calc(100% / 3). Wynik musi pasować do właściwości, więc calc(10px * 3px), czyli piksele do kwadratu, w width nie zadziała.

Najwięcej możliwości daje połączenie ze zmiennymi CSS. Zmienna może przechowywać samą liczbę, a calc() nada jej jednostkę: calc(var(--postep) * 1%). Odstępy możesz też liczyć z jednej wartości bazowej, np. calc(var(--odstep) * 2). Funkcje wolno zagnieżdżać, a wewnętrzne calc() można zastąpić zwykłymi nawiasami.

Gdy wartość ma mieć górny albo dolny limit, zamiast rozbudowanych obliczeń użyj min(), max() lub clamp(). W nich też piszesz działania bez słowa calc, np. min(100% - 2rem, 60ch).

Składnia

#
Składnia
właściwość: calc(<wartość> <operator> <wartość>);

operatory: +  -  *  /

Typowe działania

#
  • calc(100% - 80px)

    szerokość rodzica minus 80 px

    Kafelek zajmuje całą szerokość ramki poza ostatnimi 80 pikselami. Ten odstęp zostaje stały bez względu na to, jak szeroka jest ramka.
  • calc(100% / 3)

    jedna trzecia rodzica

    Dzielenie przez liczbę: kafelek ma dokładnie jedną trzecią szerokości ramki.
  • calc(var(--n) * 40px)

    4 × 40px = 160px

    Liczba ze zmiennej zamieniona na długość. Zmień --n, a szerokość przeliczy się sama.
  • calc(1rem + 2vw)

    16px + 2% szerokości okna

    Rozmiar tekstu złożony z części stałej i części zależnej od okna. Na szerszych ekranach tekst rośnie, ale nigdy nie spada poniżej 16 px.
  • calc(50% - 40px)

    środek rodzica

    Klasyczne wyśrodkowanie elementu o znanej szerokości: lewy margines to połowa rodzica minus połowa kafelka.
  • calc(360deg / 8)

    45deg

    Działania wykonasz też na kątach i czasie. Tu kąt obrotu to jedna ósma pełnego obrotu, czyli 45 stopni.

Typowe działania w praktyce

#

calc(100% - 80px)

Kafelek zajmuje całą szerokość ramki poza ostatnimi 80 pikselami. Ten odstęp zostaje stały bez względu na to, jak szeroka jest ramka.
.demo { width: calc(100% - 80px); }

calc(100% / 3)

Dzielenie przez liczbę: kafelek ma dokładnie jedną trzecią szerokości ramki.
.demo { width: calc(100% / 3); }

calc(var(--n) * 40px)

Liczba ze zmiennej zamieniona na długość. Zmień --n, a szerokość przeliczy się sama.
.demo {
  --n: 4;
  width: calc(var(--n) * 40px);
}

calc(1rem + 2vw)

Rozmiar tekstu złożony z części stałej i części zależnej od okna. Na szerszych ekranach tekst rośnie, ale nigdy nie spada poniżej 16 px.
.demo { font-size: calc(1rem + 2vw); }

calc(50% - 40px)

Klasyczne wyśrodkowanie elementu o znanej szerokości: lewy margines to połowa rodzica minus połowa kafelka.
.demo {
  width: 80px;
  margin-left: calc(50% - 40px);
}

calc(360deg / 8)

Działania wykonasz też na kątach i czasie. Tu kąt obrotu to jedna ósma pełnego obrotu, czyli 45 stopni.
.demo {
  width: 80px;
  margin: 16px auto;
  rotate: calc(360deg / 8);
}

Więcej przykładów

#
Baner na całą szerokość okna w wąskiej kolumnie
CSS
.article {
  max-width: 280px;
  margin-inline: auto;
}

.full-bleed {
  margin-inline: calc(50% - 50vw);
}
Podgląd

Kolumna artykułu ma 280 px, a baner i tak sięga krawędzi ramki. Ujemny margines 50% - 50vw to dokładnie odległość od krawędzi kolumny do krawędzi okna.

Obsługa przeglądarek

#

Szeroko dostępne

Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.

  • Chrome
  • Edge
  • Firefox
  • Safari

Dobre praktyki

#
  • Zawsze otaczaj + i - spacjami. Zapis calc(100%-20px) jest błędny i przeglądarka pominie całą deklarację.
  • Liczbę ze zmiennej zamienisz na jednostkę mnożeniem, np. calc(var(--n) * 1px). Doklejenie jednostki, czyli var(--n)px, nie zadziała.
  • Do ograniczania wartości używaj clamp(), min() i max() zamiast składać warunki w calc(). Kod będzie krótszy i czytelniejszy.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.