Glossary

CSS calc()

CSS calc() is a math function that computes a value from addition, subtraction, multiplication and division, so you can mix units such as percent and pixels in one property. It is defined in the W3C CSS Values and Units Module Level 4. The rule people trip on most is that + and - need spaces around them, so calc(10px + 5px) works and calc(10px+5px) does not.

How it works

calc() holds one calculation made of values and the four operators, with parentheses for grouping. It follows normal precedence: and / bind tighter than + and -, and equal operators go left to right. The spec's example is calc(2 + 3 4), which equals 14, while calc((2 + 3) * 4) equals 20.

The unit rules are what make errors:

  • Addition and subtraction need both sides to be the same type, though lengths and percentages may mix, such as 100% - 40px.
  • Multiplication needs at least one side to be a plain number, so 10px * 5px is invalid.
  • Division needs a plain number on the right, so 10px / 5px is invalid in the syntax tested below.
  • Components can be literal values, other math functions or var() references that resolve to a valid type.
  • Nested parentheses and nested calc() behave the same.

The browser resolves percentages at layout time against the property's reference box, which is why 100% - 40px works even though the percentage is unknown when the CSS is parsed.

#a { width: calc(100% - 40px); }
#c { width: calc((2 + 3) * 4 * 1px); }
#d { width: calc(10px+5px); }
#e { width: calc(10px + 5px); }

Computed widths in headless Chromium 141 inside a 600px wide parent:

#a: 560px
#c: 20px
#d: 600px
#e: 15px

#d is invalid because of the missing spaces, so the declaration was dropped and the block div fell back to its auto width of 600px. CSS.supports also returned false for calc(10px+5px), and false for 10px * 5px and 10px / 5px.

Can you use CSS variables inside calc()?

Yes, calc() accepts var() references, which makes it the standard way to derive values from a token. In headless Chromium 141 with --gap: 8px and --n: 3, calc(var(--gap) var(--n)) computed to 24px. A unitless variable needs a unit multiplier: calc(var(--n) 1px - 2px) computed to 1px.

Common pitfalls

  • Missing spaces around + and -: calc(10px+5px) is invalid and the whole declaration is ignored. Always put a space on both sides. Spaces around * and / are optional.
  • Multiplying two lengths: calc(10px * 5px) is invalid. One operand must be a unitless number.
  • Dividing by zero: calc(10px / 0) passed CSS.supports in Chromium 141, so a parse check does not protect you. The result is decided later, so treat zero divisors as a bug to avoid.
  • Using a bare number as a length: calc(2 + 3 4) is 14 but not a length. Add 1px to get a length.
  • Assuming it replaces clamp(): calc() has no minimum or maximum. Use CSS clamp() when the value must stay in a range.

Related terms

  • CSS clamp() — adds a minimum and maximum around a calculation.
  • Viewport units — a frequent operand, as in 100vh minus a header height.
  • Dynamic viewport units — often combined with calc() for mobile layouts.
  • CSS Grid — grid track sizes frequently use calc().
  • Flexbox — flex-basis values can use calc().

See also