calc

calc — CSS-функция, которая вычисляет значение из математического выражения, позволяя смешивать разные единицы измерения (px + %, rem - vw и т.д.).

Зачем нужно

calc позволяет выполнять арифметику прямо в CSS, смешивая единицы, которые невозможно скомбинировать иначе. Например: «100% ширины минус 250px сайдбара» — без calc это невозможно записать.

Где используется

  • Вычисление размеров с учётом фиксированных и процентных значений
  • Адаптивные отступы и размеры
  • Работа с CSS-переменными (арифметика с var)
  • Вычисление позиций при позиционировании
  • Динамическая типографика

Предпосылки

Синтаксис

.element {
  /* Базовый синтаксис */
  width: calc(100% - 250px);
  height: calc(100vh - 80px);
  font-size: calc(16px + 0.5vw);
  padding: calc(1rem + 8px);
}

Операторы

.element {
  /* Сложение */
  width: calc(100% + 20px);

  /* Вычитание */
  height: calc(100vh - 60px);

  /* Умножение (одно значение — число без единицы) */
  width: calc(100% * 0.5);
  font-size: calc(1rem * 1.5);

  /* Деление (делитель — число без единицы) */
  width: calc(100% / 3);
  gap: calc(var(--spacing) / 2);
}

Пробелы вокруг + и - обязательны! calc(100%-20px) не сработает. Пробелы вокруг * и / рекомендуются, но не обязательны.

Смешивание единиц

/* Контент = 100% минус сайдбар */
.content {
  width: calc(100% - 250px);
}

/* Полная высота минус шапка и подвал */
.main {
  min-height: calc(100dvh - 80px - 60px);
}

/* rem + vw для адаптивного шрифта */
h1 {
  font-size: calc(1.5rem + 1vw);
}

/* % + px для точных расчётов */
.column {
  width: calc(33.333% - 20px);
  margin: 10px;
}

calc с CSS-переменными

:root {
  --header-height: 80px;
  --footer-height: 60px;
  --sidebar-width: 250px;
  --spacing: 16px;
  --columns: 3;
}

.main {
  min-height: calc(100dvh - var(--header-height) - var(--footer-height));
  padding: var(--spacing);
}

.content {
  width: calc(100% - var(--sidebar-width) - var(--spacing) * 2);
}

/* Динамическая ширина колонок */
.column {
  width: calc(100% / var(--columns) - var(--spacing));
}

/* Преобразование числа без единицы в px */
:root {
  --size: 20;
}
.box {
  width: calc(var(--size) * 1px); /* 20px */
}

Вложенный calc

.element {
  /* calc внутри calc — допустимо, но можно упростить */
  width: calc(100% - calc(var(--sidebar) + var(--gap)));

  /* Проще: */
  width: calc(100% - var(--sidebar) - var(--gap));
}

Практические примеры

Центрирование с отступом

.centered-box {
  width: calc(100% - 48px); /* 24px отступ с каждой стороны */
  max-width: 1200px;
  margin-inline: auto;
}

Grid с фиксированными промежутками

.grid-3-cols {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.grid-3-cols > * {
  /* 3 колонки с учётом 2 промежутков по 20px */
  width: calc((100% - 20px * 2) / 3);
}

Полноэкранные секции с шапкой

.hero {
  min-height: calc(100dvh - var(--header-height));
  display: grid;
  place-items: center;
}

Адаптивные отступы

:root {
  --base-spacing: 16px;
}

section {
  padding: calc(var(--base-spacing) * 3) calc(var(--base-spacing) * 1.5);
}

@media (max-width: 768px) {
  section {
    padding: calc(var(--base-spacing) * 2) var(--base-spacing);
  }
}

Частые ошибки

  1. Нет пробелов вокруг + и -:
    /* ОШИБКА */
    width: calc(100%-20px);
    /* ПРАВИЛЬНО */
    width: calc(100% - 20px);
    
  2. Деление на значение с единицей:
    /* ОШИБКА */
    width: calc(100% / 3px); /* Делить на px нельзя */
    /* ПРАВИЛЬНО */
    width: calc(100% / 3);
    
  3. Умножение двух значений с единицами:
    /* ОШИБКА */
    width: calc(10px * 20px); /* px * px = px² — невалидно */
    /* ПРАВИЛЬНО */
    width: calc(10px * 20); /* = 200px */
    
  4. calc для нулевого значения — не нужен:
    margin: calc(0px); /* Бессмысленно, просто 0 */
    

Практика

  • Создать layout «100% минус сайдбар» через calc
  • Вычислить высоту контента: 100dvh - header - footer
  • Использовать calc с CSS-переменными для динамических отступов
  • Создать 3-колоночный layout с calc((100% - gap * 2) / 3)
  • Сделать адаптивный font-size через calc(1rem + 0.5vw)

Связанные темы

Ресурсы