Иногда нужное значение нельзя записать одним числом, потому что оно складывается из разных величин. Например: «на всю высоту экрана минус шапка в 60 пикселей», «половина ширины родителя минус отступ», «на всю ширину, но с учётом фиксированной колонки сбоку». Проценты и пиксели тут смешиваются, и заранее посчитать результат невозможно — он зависит от экрана. Функция calc() решает это: она позволяет выполнять арифметику прямо в CSS, комбинируя разные единицы. Браузер сам вычислит результат и пересчитает его при изменении размеров.
После этого урока вы сможете задавать размеры, которые вычисляются на лету из нескольких величин, — смешивать проценты с пикселями, вычитать фиксированные части и строить точные, отзывчивые макеты.
Что уже умеем / что добавим
Вы умеете задавать гибкие размеры и хранить значения в переменных. Но пока не могли комбинировать разные единицы в одном значении — например, вычесть пиксели из процентов. Теперь добавим calc() — арифметику в CSS. В сквозном проекте мы точно рассчитаем высоту главного экрана сайта компании и ширину контентной области с учётом отступов.
Что вы узнаете в рамках статьи
- Что делает функция
calc()и какие операции доступны. - Как смешивать разные единицы (проценты, пиксели,
vh) в одном значении. - Почему важны пробелы вокруг знаков операций.
- Как сочетать
calc()с CSS-переменными.
Ключевые термины
calc()— функция для арифметических вычислений в значениях CSS.- Операции — сложение (
+), вычитание (), умножение (), деление (/). - Смешение единиц — комбинирование разных единиц (например,
100% - 40px) в одном выражении. vh— единица, равная 1% высоты окна (из курса об адаптиве).
Что такое calc() и какие операции доступны
calc() вычисляет значение по формуле, которую вы пишете внутри скобок. Доступны четыре арифметические операции: сложение, вычитание, умножение и деление. Результат подставляется как обычное значение свойства:
.box {
width: calc(100% - 40px);
}
Ширина блока будет равна всей ширине родителя минус 40 пикселей. Самое ценное здесь — смешение единиц: 100% и 40px невозможно сложить «в голове» заранее, ведь проценты зависят от размера родителя, но браузер вычислит это сам в момент отрисовки и пересчитает при изменении размеров. Умножение и деление тоже работают: calc(100% / 3) даст точную треть ширины, а calc(1rem * 2) — удвоенный размер.
Смешение разных единиц
Главная сила calc() — соединять единицы, которые иначе несовместимы. Классический пример — блок на всю высоту экрана за вычетом фиксированной шапки:
.hero {
height: calc(100vh - 60px);
}
Здесь 100vh — вся высота окна, а 60px — высота фиксированной шапки. Результат — ровно та высота, что остаётся под шапкой, на любом экране. Без calc() так не записать: 100vh и 60px — разные единицы. Подобным образом считают ширину контента рядом с боковой панелью (calc(100% - 250px)), отступы, размеры сетки. Комбинировать можно и больше двух величин: calc(100% - 40px - 1rem) — браузер справится с любой корректной формулой.
Пробелы вокруг операций
У calc() есть одна строгая, но легко забываемая деталь: вокруг знаков сложения и вычитания обязательны пробелы. Без них выражение не вычислится:
/* Правильно: пробелы вокруг минуса есть */
width: calc(100% - 40px);
/* Ошибка: пробелов нет, значение не сработает */
width: calc(100%-40px);
Причина в том, что минус и плюс без пробелов браузер может принять за знак самого числа (например, -40px — это отрицательное число, а не вычитание). Поэтому правило простое: всегда ставьте пробелы вокруг + и -. Для * и / пробелы формально не обязательны, но их тоже принято ставить для читаемости. Это самая частая причина, по которой «calc() не работает», — стоит проверять пробелы в первую очередь.
Сочетание с переменными
calc() особенно хорош вместе с CSS-переменными: вы храните базовые значения в переменных, а из них вычисляете производные. Это делает стили одновременно гибкими и точными:
:root {
--header-height: 64px;
--gap: 24px;
}
.hero {
height: calc(100vh - var(--header-height));
}
.content {
width: calc(100% - var(--gap) * 2);
}
Высота главного экрана считается от высоты шапки, заданной переменной, а ширина контента — с учётом двойного отступа. Если поменять --header-height в одном месте, все вычисления обновятся сами. Такое сочетание — основа аккуратных, поддерживаемых макетов: смысловые величины лежат в переменных, а calc() собирает из них нужные размеры. Обратите внимание, как var() спокойно подставляется прямо внутрь формулы.
Применяем в проекте
Рассчитаем главный экран сайта компании так, чтобы он занимал всю высоту окна за вычетом шапки, и зададим ширину контентной области с учётом отступов. Возьмём высоту шапки и отступ из переменных, а размеры соберём через calc().
:root {
--header-height: 64px;
--gap: 24px;
}
.hero {
height: calc(100vh - var(--header-height));
}
.content {
width: calc(100% - var(--gap) * 2);
margin: 0 auto;
}
Откройте страницу: главный экран занимает ровно ту высоту, что остаётся под шапкой, — без «наезда» и без лишней прокрутки, на любом размере окна. Контентная область точно вписана по ширине с учётом отступов по краям. Мы задали это формулами, которые браузер пересчитывает автоматически при изменении экрана. А поскольку исходные величины лежат в переменных, менять их легко и безопасно — вычисления подстроятся сами.
Частые ошибки
- Нет пробелов вокруг и
+.
calc(100%-40px)не сработает; вокруг сложения и вычитания пробелы обязательны. - Деление на ноль или на единицу с единицей.
Делить и умножать можно только на число без единицы;calc(100% / 3px)некорректно. - Смешивать несовместимое.
Внутриcalc()единицы должны быть складываемыми по смыслу; проверяйте, что формула имеет физический смысл. - Усложнять там, где не нужно.
Если значение можно задать одним числом,calc()ни к чему; применяйте его, когда действительно нужно смешать единицы.
Итоги
Отличная работа — вы научились вычислять значения прямо в CSS! Теперь вы умеете использовать calc() для сложения, вычитания, умножения и деления, смешивать разные единицы вроде процентов, пикселей и vh, помните про обязательные пробелы вокруг операций и умеете сочетать calc() с переменными. В сквозном проекте вы точно рассчитали высоту главного экрана и ширину контента сайта компании.
Прекрасный прогресс — ваши макеты стали точными и гибкими одновременно! В следующем уроке мы займёмся современными эффектами: тенями, градиентами, фильтрами и модным «стеклянным» размытием через backdrop-filter, которые придадут сайту глубину и стиль.