Пошук уроків, статей та іншого контенту
Використаєте calc() для обчислення розмірів, відступів і позицій із поєднанням різних одиниць CSS.
calc()calc() — це CSS-функція для обчислення значень під час відображення сторінки. Вона дає змогу поєднувати різні одиниці вимірювання, наприклад:
відсотки та пікселі;
rem та пікселі;
ширину контейнера та фіксований відступ;
значення позиції та розмір елемента.
Замість окремих правил для різних розмірів екрана можна описати залежність безпосередньо в CSS:
.sidebar {
width: 240px;
}
.content {
width: calc(100% - 240px);
}Ширина .content автоматично обчислюється як ширина батьківського елемента мінус 240px.
calc()Базовий синтаксис:
property: calc(expression);Наприклад:
.card {
width: calc(100% - 32px);
margin-left: calc(1rem + 8px);
}Усередині calc() можна використовувати арифметичні оператори:
+ — додавання;
- — віднімання;
* — множення;
/ — ділення.
Для операторів + і - потрібно залишати пробіли з обох боків:
width: calc(100% - 40px);Такий запис є правильним. Без пробілів вираз може бути інтерпретований некоректно:
/* Неправильно або неоднозначно */
width: calc(100%-40px);Основна перевага calc() — можливість поєднувати одиниці, які не можна безпосередньо скласти в одному статичному значенні.
Типовий приклад — елемент, який займає всю доступну ширину, крім фіксованих внутрішніх відступів:
.container {
width: calc(100% - 32px);
margin: 0 auto;
}Якщо ширина батьківського елемента дорівнює 1200px, ширина .container буде 1168px.
rem та пікселіМожна створити відступ, що складається з масштабованої та фіксованої частин:
.title {
margin-bottom: calc(1rem + 4px);
}Якщо 1rem дорівнює 16px, результат буде 20px. Якщо базовий розмір шрифту зміниться, частина в rem також зміниться.
rem.panel {
width: calc(75% - 2rem);
}Панель займатиме 75% ширини батьківського елемента, але буде на 2rem вужчою.
calc() часто застосовують для ширини та висоти елементів.
.layout {
display: flex;
}
.sidebar {
width: 280px;
}
.main {
width: calc(100% - 280px);
}Основна частина займає весь доступний простір за винятком ширини бічної панелі.
Для надійнішого flex-макета основній частині можна вказати flex-basis:
.main {
flex: 0 1 calc(100% - 280px);
}За допомогою calc() можна врахувати висоту іншого елемента. Наприклад, якщо верхня панель має висоту 64px:
.page {
min-height: calc(100vh - 64px);
}100vh відповідає висоті області перегляду браузера. Секція займе всю висоту за винятком верхньої панелі.
Динамічні відступи допомагають зберегти однакову структуру на різних екранах.
.content {
padding: calc(1rem + 2vw);
}У цьому прикладі:
1rem створює базовий відступ;
2vw додає частину ширини області перегляду;
підсумковий відступ змінюється залежно від розміру вікна.
Можна окремо обчислювати горизонтальні та вертикальні відступи:
.section {
padding: calc(2rem + 1vw) calc(1rem + 2vw);
}Перше значення застосовується зверху та знизу, друге — ліворуч і праворуч.
calc() корисний, коли позиція елемента залежить від його розміру або фіксованого відступу.
.badge {
position: absolute;
right: calc(100% + 12px);
}Елемент буде розташований праворуч відносно своєї позиції на відстані, що дорівнює 100% плюс 12px.
Інший приклад:
.modal {
position: fixed;
left: calc(50% - 200px);
width: 400px;
}Модальне вікно шириною 400px буде розташоване приблизно по центру:
50% визначає середину області перегляду;
200px — половина ширини модального вікна.
Для центрування зазвичай зручніше використовувати transform, але цей приклад показує принцип обчислення позиції.
У calc() можна множити значення на число або ділити на число:
.card {
width: calc(20rem * 2);
padding: calc(2rem / 2);
}Результатом буде:
ширина 40rem;
внутрішній відступ 1rem.
Множення двох значень з одиницями не допускається:
/* Неправильно */
width: calc(10px * 2px);У результаті множення одна зі сторін має бути числом без одиниці:
width: calc(10px * 2);Нижче наведено сторінку з верхньою панеллю, бічною навігацією та основним вмістом. Розмір основної області обчислюється за допомогою calc().
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Приклад calc()</title>
<style>
* {
box-sizing: border-box;
}
:root {
--header-height: 64px;
--sidebar-width: 240px;
}
body {
margin: 0;
font-family: Arial, sans-serif;
color: #1f2937;
background: #f3f4f6;
}
.header {
height: var(--header-height);
display: flex;
align-items: center;
padding: 0 24px;
color: white;
background: #2563eb;
}
.layout {
display: flex;
min-height: calc(100vh - var(--header-height));
}
.sidebar {
flex: 0 0 var(--sidebar-width);
padding: 24px 16px;
background: #dbeafe;
}
.main {
width: calc(100% - var(--sidebar-width));
padding: calc(1rem + 1vw);
}
.grid {
display: grid;
grid-template-columns: repeat(3, calc((100% - 32px) / 3));
gap: 16px;
}
.card {
min-height: 160px;
padding: 20px;
border-radius: 12px;
background: white;
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
}
@media (max-width: 700px) {
.layout {
display: block;
}
.sidebar {
width: 100%;
}
.main {
width: 100%;
}
.grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<header class="header">
<strong>Мій застосунок</strong>
</header>
<div class="layout">
<aside class="sidebar">
<nav>
<p>Головна</p>
<p>Профіль</p>
<p>Налаштування</p>
</nav>
</aside>
<main class="main">
<div class="grid">
<article class="card">
<h2>Картка 1</h2>
<p>Ширина кожної картки обчислюється динамічно.</p>
</article>
<article class="card">
<h2>Картка 2</h2>
<p>Відстань між картками враховується у формулі.</p>
</article>
<article class="card">
<h2>Картка 3</h2>
<p>Макет пристосовується до ширини контейнера.</p>
</article>
</div>
</main>
</div>
</body>
</html>У правилі:
grid-template-columns: repeat(3, calc((100% - 32px) / 3));від загальної ширини контейнера віднімаються два проміжки по 16px, після чого залишок ділиться на три колонки.
Вирази calc() можна вкладати один в один:
.element {
width: calc(100% - calc(2rem + 16px));
}Внутрішній вираз спочатку обчислює суму 2rem + 16px, а потім ця сума віднімається від 100%.
У багатьох випадках додаткове вкладення не потрібне. Той самий вираз можна записати коротше:
.element {
width: calc(100% - 2rem - 16px);
}Такий запис зазвичай легше читати.
calc() із CSS-зміннимиcalc() добре працює з користувацькими властивостями:
:root {
--sidebar-width: 240px;
--content-gap: 24px;
}
.content {
width: calc(100% - var(--sidebar-width) - var(--content-gap));
}Якщо зміниться значення --sidebar-width, ширина .content автоматично перераховується.
Це зменшує кількість дубльованих значень і полегшує підтримку стилів.
calc()calc() виконує обчислення, але не визначає, чи підходить результат для конкретної властивості.
Наприклад, від’ємна ширина не має практичного сенсу:
.element {
width: calc(20px - 40px);
}Браузер обчислить значення, але властивість width не зможе використати від’ємну ширину як звичайний розмір.
Також результат залежить від контексту:
.child {
width: calc(100% - 20px);
}100% тут обчислюється відносно ширини батьківського елемента, а не всієї сторінки.
+ і -/* Погано */
width: calc(100%-20px);
/* Добре */
width: calc(100% - 20px);Не кожні CSS-значення можна арифметично поєднати:
/* Неправильно */
color: calc(red + blue);calc() призначений переважно для числових значень: розмірів, відступів, позицій та інших властивостей, що приймають числа з одиницями.
box-sizingЯкщо елемент має width: 100% і додаткові горизонтальні padding, його фактичний розмір може перевищити ширину батьківського елемента. Для передбачуваного розміру часто використовують:
* {
box-sizing: border-box;
}У такому разі внутрішні відступи та межі враховуються в заданій ширині.
calc()Не потрібно застосовувати calc(), якщо значення можна записати безпосередньо:
/* Зайве */
padding: calc(16px + 8px);
/* Простіше */
padding: 24px;calc() особливо корисний тоді, коли хоча б одна частина виразу залежить від батьківського елемента, області перегляду або CSS-змінної.
calc() обчислює CSS-значення під час відображення сторінки.
У ньому можна поєднувати різні одиниці: %, px, rem, vw, vh.
Основні оператори — +, -, * і /.
Біля операторів + та - потрібно використовувати пробіли.
calc() підходить для розмірів, відступів і позицій.
Вирази можна комбінувати з CSS-змінними через var().
Значення 100% залежить від контексту батьківського елемента.
Не варто використовувати calc() для простих статичних обчислень, які можна виконати заздалегідь.