CSS Calc Function

The calc() function lets you perform math directly inside CSS property values. It mixes different unit types in a single expression — something that regular CSS values cannot do. Instead of calculating pixel values manually, you let the browser do the math at render time.

Why calc() Exists

DIAGRAM — The problem calc() solves:

You want a sidebar to be exactly 300px wide
and the main content to fill the rest.

Without calc():
  You guess pixel values, recalculate for each screen size,
  or use JavaScript. Complex and error-prone.

With calc():
  .main { width: calc(100% - 300px); }

Browser calculates the right value on every screen automatically.

Basic Syntax

property: calc(expression);

The expression uses standard math operators:

  • + addition
  • - subtraction
  • * multiplication
  • / division

Important: The + and - operators must have a space on each side. This is required — calc(100%-300px) is invalid, calc(100% - 300px) is correct.

Mixing Units

This is the superpower of calc(). You can mix percentages, pixels, rem, vh, and other units in one expression.

/* Percentage minus pixels */
.main-content {
  width: calc(100% - 280px);
}

/* Viewport height minus a fixed header */
.page-body {
  min-height: calc(100vh - 64px);
}

/* Relative to root font size */
.card {
  padding: calc(1rem + 8px);
}

Common Use Cases

Sidebar + Main Layout

DIAGRAM — Sidebar + Content layout:

Page: 100% wide
├── Sidebar: 260px (fixed)
└── Main: rest of the space

.sidebar {
  width: 260px;
  float: left;
}

.main {
  width: calc(100% - 260px);
  float: left;
}

On a 1000px screen: main = calc(1000px - 260px) = 740px
On a 800px screen:  main = calc(800px - 260px)  = 540px
Automatically adapts!

Full-Viewport Page Minus Header

header {
  height: 60px;
}

main {
  min-height: calc(100vh - 60px);
  /* Fills the visible screen below the header */
}
DIAGRAM — Viewport minus header:

┌────────────────────────┐  ─────
│ Header (60px)          │    ↑
├────────────────────────┤    │ 100vh
│                        │    │
│ Main content           │    │
│ (calc(100vh - 60px))   │    ↓
└────────────────────────┘  ─────

Centered Element with Offset

.tooltip {
  position: absolute;
  left: calc(50% - 80px); /* centered, minus half of tooltip width */
  width: 160px;
}

Equal Columns with Gap

/* Three equal columns with 20px gaps between them */
/* (2 gaps total between 3 columns) */
.col {
  width: calc((100% - 40px) / 3);
  /* 40px = 20px gap × 2 */
}

Fluid Typography

h1 {
  font-size: calc(1.5rem + 2vw);
  /* Combines a base size with a viewport-relative boost */
  /* Never smaller than 1.5rem, grows as viewport widens */
}
DIAGRAM — Fluid font size with calc():

Viewport 320px:  font-size = 1.5rem + 6.4px  ≈ 30px
Viewport 768px:  font-size = 1.5rem + 15.4px ≈ 39px
Viewport 1200px: font-size = 1.5rem + 24px   ≈ 48px

Smoothly grows without media query breakpoints!

Negative Space / Bleed

/* Make an element bleed outside its container by 24px on each side */
.full-bleed {
  width: calc(100% + 48px);
  margin-left: -24px;
}

Using calc() with CSS Variables

calc() and CSS custom properties work together naturally.

:root {
  --header-height: 64px;
  --sidebar-width: 280px;
  --gap: 24px;
}

.page-content {
  min-height: calc(100vh - var(--header-height));
  width: calc(100% - var(--sidebar-width) - var(--gap));
}

Nested calc()

You can nest calc() inside itself, though modern browsers also accept plain arithmetic without nesting.

.box {
  width: calc(calc(100% - 60px) / 3);

  /* Same result, modern syntax (no nesting needed): */
  width: calc((100% - 60px) / 3);
}

calc() with Multiplication and Division

For * and /, at least one value must be a unitless number.

/* Valid */
width: calc(50% * 2);   /* 100% */
width: calc(100px / 4); /* 25px */
width: calc(2 * 100px); /* 200px */

/* Invalid */
width: calc(50% * 20%); /* Two percentages cannot be multiplied */

Other Math Functions (Modern CSS)

CSS has added several related math functions. They work alongside calc().

  • min(a, b) — uses the smaller value. Great for capping widths.
  • max(a, b) — uses the larger value. Great for setting minimums.
  • clamp(min, preferred, max) — constrains a value between a minimum and maximum.
/* Width is at most 600px, but responsive below that */
width: min(600px, 100%);

/* Font size between 1rem and 2rem, ideally 2.5vw */
font-size: clamp(1rem, 2.5vw, 2rem);
DIAGRAM — clamp(1rem, 2.5vw, 2rem):

Viewport 320px:  2.5vw = 8px  → clamp gives 1rem (16px) ← minimum
Viewport 800px:  2.5vw = 20px → clamp gives 1.25rem (20px) ← in range
Viewport 1200px: 2.5vw = 30px → clamp gives 2rem (32px) ← maximum

Text grows smoothly and is never too small or too large.

When to Use calc()

SituationUse calc()?
Mix percentage and pxYes — only calc() can do this
Viewport minus fixed headerYes — calc(100vh - 64px)
Fluid font sizingYes — or use clamp()
Equal columns with gapYes — or use CSS Grid with gap
Convert units (px to rem)No — use the unit directly
Simple single-unit mathNo — just write the value

calc() turns the browser into your calculator. It keeps your CSS readable — you see the intent ("100% minus the sidebar") rather than a magic number — and it adapts automatically as the context changes.

Leave a Comment

Your email address will not be published. Required fields are marked *