The CSS calc() function

By

Learn how the CSS calc() function performs math on values, like calc(80% - 100px), mixing percentages and lengths with the +, -, * and / operators.

~~~

The calc() function lets you perform math operations on CSS values. You write an expression like calc(80% - 100px) and the browser computes the result for you.

The reason it exists is that you often need to mix units. You can’t tell CSS “make this 100% wide, minus 250px for the sidebar” without it. No single unit can express that, because the percentage depends on the parent size, which you don’t know in advance.

This is how it works:

main {
  max-width: calc(80% - 100px);
}

It returns a length value, so you can use it anywhere you’d write a pixel value: width, margin, font-size, top, and so on.

Which operators can you use?

You can perform:

Examples:

main {
  max-width: calc(50% / 3);
}
main {
  max-width: calc(50% + 3px);
}

You can mix any units that make sense together. Percentages with pixels, rems with pixels, viewport units with rems:

.hero {
  height: calc(100vh - 4rem);
}

This is a common one: a section that fills the viewport, minus the height of a fixed header.

Be careful with spaces

With addition and subtraction, the space around the operator is mandatory:

/* works */
width: calc(100% - 250px);

/* does NOT work */
width: calc(100%-250px);

Without the spaces, the browser reads -250px as a negative value stuck to the percentage, the expression is invalid, and the whole declaration is dropped. Nothing breaks loudly. The rule just doesn’t apply, which makes this annoying to debug. If a calc() seems ignored, check the spaces first.

Multiplication and division don’t have this requirement, but I add the spaces anyway for consistency.

Using calc() with CSS variables

calc() pairs nicely with custom properties. You can store a value once and derive others from it:

:root {
  --header-height: 60px;
}

.content {
  min-height: calc(100vh - var(--header-height));
}

Change the variable, and every calculation that uses it updates.

One limitation: you can multiply and divide by numbers, but not by two lengths. calc(100px * 2) is fine. calc(100px * 2px) is invalid, because “pixels squared” is not a CSS unit.

If you’re mixing units because you’re converting between px and rem, my free CSS units converter can help.

Tagged: CSS · All topics
~~~

Related posts about css: