Комментарии (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 логику.