← Назад к вопросам

Что такое функция calc в CSS?

1.0 Junior🔥 281 комментариев
#HTML и CSS

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

calc() функция: динамические вычисления в CSS

calc() — это CSS функция, которая позволяет выполнять математические вычисления в значениях свойств. Вместо хардкода значений или JavaScript логики, можно писать формулы прямо в CSS. Это мощный инструмент для адаптивного дизайна, особенно при работе с относительными единицами и когда размеры элементов зависят друг от друга.

Базовый синтаксис и примеры

/* Базовая арифметика */
.element {
  width: calc(100% - 40px); /* 100% минус 40px (padding/margin) */
  height: calc(100vh - 60px); /* Высота экрана минус header */
  padding: calc(1rem + 5px); /* 1rem + 5px */
  margin: calc(20px * 2); /* 20px умножить на 2 = 40px */
  font-size: calc(1em / 2); /* 1em разделить на 2 */
}

/* Нельзя пропускать пробелы вокруг + и - */
.wrong {
  width: calc(100%-40px); /* ОШИБКА! Без пробелов */
}

.correct {
  width: calc(100% - 40px); /* ПРАВИЛЬНО! С пробелами */
}

/* Можно комбинировать единицы */
.responsive {
  width: calc(100% - 2rem); /* % и rem */
  height: calc(100vh - 60px); /* vh и px */
  font-size: calc(1.5em + 2vw); /* em и vw */
}

/* Вложенные calc */
.nested {
  width: calc((100% - 40px) / 2); /* Можно использовать скобки */
  margin-top: calc(var(--spacing) * 2 + 10px); /* CSS переменные */
}

Практические примеры использования

/* ==================== ПРИМЕР 1: Адаптивный контейнер ==================== */
.container {
  width: calc(100% - 40px); /* Полная ширина минус padding */
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

/* ==================== ПРИМЕР 2: Сетка без gap (старые браузеры) ==================== */
.grid {
  display: grid;
  grid-template-columns: repeat(3, calc(33.333% - 10px));
  gap: 10px;
  /* Каждая колонна = 1/3 ширины минус часть gap */
}

/* ==================== ПРИМЕР 3: Динамический шрифт ==================== */
.heading {
  /* Шрифт масштабируется: минимум 24px, максимум 48px */
  /* При 320px экране = 24px, при 1280px экране = 48px */
  font-size: calc(1.5rem + 1vw);
}

/* ==================== ПРИМЕР 4: Высота без header ==================== */
.page-content {
  height: calc(100vh - 60px); /* 100vh минус высота header */
  overflow-y: auto;
}

/* ==================== ПРИМЕР 5: Flex элементы с фиксированным зазором ==================== */
.flex-container {
  display: flex;
  gap: 10px;
}

.flex-item {
  width: calc(25% - 10px); /* 25% минус часть gap */
  flex: 1;
}

/* ==================== ПРИМЕР 6: Aspect ratio до появления aspect-ratio ==================== */
.square {
  width: 100%;
  padding-bottom: 100%; /* 1:1 aspect ratio */
  position: relative;
}

.square-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(100% - 20px); /* Высота с учётом padding */
}

Использование с CSS переменными (CSS Custom Properties)

/* Определение переменных */
:root {
  --spacing: 1rem;
  --header-height: 60px;
  --sidebar-width: 250px;
  --border-width: 2px;
}

/* Использование в calc */
.main-content {
  width: calc(100% - var(--sidebar-width) - var(--border-width) * 2);
  margin-left: calc(var(--sidebar-width) + var(--border-width));
  padding: calc(var(--spacing) * 2);
  min-height: calc(100vh - var(--header-height));
}

/* Реактивные переменные для разных экранов */
@media (max-width: 768px) {
  :root {
    --sidebar-width: 0;
    --spacing: 0.5rem;
  }
}

/* Теперь .main-content автоматически пересчитается */

React компонент с calc

import { CSSProperties } from 'react';

interface ResponsiveBoxProps {
  totalPadding: number;
  screenHeight: number;
  headerHeight: number;
}

export function ResponsiveBox({
  totalPadding = 40,
  screenHeight = 100,
  headerHeight = 60,
}: ResponsiveBoxProps) {
  // Можно использовать CSS-in-JS для calc
  const styles: CSSProperties = {
    width: `calc(100% - ${totalPadding}px)`,
    height: `calc(${screenHeight}vh - ${headerHeight}px)`,
    padding: `${totalPadding / 2}px`,
  };

  return (
    <div style={styles}>
      <p>Размер вычисляется динамически!</p>
    </div>
  );
}

// Или с Tailwind + CSS переменные (рекомендуется)
export function ResponsiveBoxWithTailwind() {
  return (
    <div
      style={{
        '--padding': '40px',
        '--header-height': '60px',
      } as CSSProperties}
      className="w-[calc(100%-var(--padding))] h-[calc(100vh-var(--header-height))]"
    >
      Content
    </div>
  );
}

Лучшие практики и ограничения

/* ✓ ЧТО РАБОТАЕТ */
.good1 { width: calc(100% - 20px); }
.good2 { height: calc(100vh - var(--header-height)); }
.good3 { font-size: calc(1rem + 0.5vw); }
.good4 { padding: calc(1em + 10px); }

/* ✗ ЧТО НЕ РАБОТАЕТ */
.bad1 { width: calc(100% - 20px auto); } /* Смешивание несовместимых единиц */
.bad2 { margin: calc(10px); } /* Просто 10px, смысла в calc нет */
.bad3 { z-index: calc(1 + 2); } /* z-index не принимает calc */

/* ОСТОРОЖНО */
.caution1 {
  /* Операции с % могут быть неинтуитивны */
  width: calc(50% + 10px); /* 50% от родителя + 10px, не от экрана */
}

.caution2 {
  /* calc не работает в селекторах или media queries */
  /* media (max-width: calc(768px - 1px)) { } ОШИБКА */
}

Производительность

calc() очень быстро вычисляется браузером. Это не требует JavaScript, не запускает Layout thrashing. Однако, если вложить слишком много вычислений, может незначительно упасть производительность.

Рекомендация: используй calc для адаптивного дизайна, но не заменяй её на сложные JavaScript логику.

Что такое функция calc в CSS? | PrepBro