A photograph of multicolored, overlapped protractors

Over the last two decades layout on the web has evolved from fixed-width designs to responsive, modular pages. CSS’s declarative “a box this wide in pixels, always” has become much more fluid and subtle. Site stylesheets often feature a mixture of units, all interacting with each other to create a design. Designers and developers need to understand the role of each CSS measurement system, but they also require a method of binding and adding these units together in stylesheets.

Into this role steps the powerful calc. For all it’s usefulness, the application of calc isn’t always obvious; its best appreciated through example. I’ll start with a simple one:

Example 1: Vertical Flush Margins

Take this lovely photograph of a waterfall by Stian Klo. The image has been floated, with a 2rem margin placed on its right side.

The image has been made fluid, set to 50% of the width of its parent. For reference, the HTML:

<img src="kirkjufellsfoss.jpg" alt style="width:50%; margin-right: 2rem; float: left;">
<p>Det er et velkjent faktum...

For this design, we want that margin to continue vertically, visually focussing the image via the negative space beneath it. The problem is that the fluidity of paragraphs means that the text will eventually creep under the image as the viewport narrows:

While there are many ways of treating this, we basically want a solution that states the following:

“Paragraphs following an image should have a left margin of 50% plus 2rem”

Using calc with a general sibling selector, that would be stated as:

img ~ p { 
	margin-left: calc(50% + 2rem); 
}

The result:

calc allows us to combine very different measurements – percentages and rem – into one result, making the margin fixed but the image fluid.

Example 2: Full-Width Elements In Padded Containers

It’s not uncommon for pages to have full-width elements displayed above padded content:

<article>
	<header>
		<img src="fredvang.jpg" alt>
	</header>
	<p>Det er et velkjent faktum at lesere distraheres av lesbart innhold på en side når man ser på dens layout...
</article>

The CSS:

* { 
	box-sizing: border-box; 
}
body {
	background: #000;
	font-family: Edelsans, sans-serif;
	line-height: 1.5; 
}
article { 
	width: 80%; margin: 0 auto;
	background: #fff;
	padding: 0 2rem; 
	color: #000; 
}
article header img { 
	width: 100%; height: auto; 
}

The problem is that padding on the <article> will also force the <header> content inwards:

We can fix that by adding a declaration for the <header> that uses calc:

article header { 
	width: calc(100% + 4rem); margin-left: -2rem; 
}

The 4rem added to the width of the <header> makes up for the 2rem padding on the left and right of the <article>:

Operations

calc can do all the basic mathematical operations you’re familiar with:

Operations in calc()
symboloperator
+addition
-subtraction
*multiplication
/division

One important point to remember is that the addition and subtraction operators must have spaces either side of them, while calc must sit directly next to the opening parenthesis. So this works:

width: calc(20% - 1rem);

But this does not:

width: calc(20%-1rem);

Neither does this:

width: calc (20% - 1rem);

This is for the simple reason that a minus sign directly in front of a value will result in it being interpreted as a negative. Multiplication and division operators do not require spaces, but they are recommended regardless, if only for the sake of consistency.

Support & Limitations

All modern browsers support calc for length units in CSS. In theory, calc should be applicable anywhere a number unit is used, which makes for some very interesting possibilities:

.box { 
	background: rgba(255, 0, 0, calc(.3 * 2)); 
}

Or this:

.box { 
	transform: rotate(calc(45deg - 2.31rad)); 
}

If the examples above are a rotated and partially transparent red box, congratulations: you have a browser that supports calc in different declarations. Most browsers carry caveats when it comes to calc in these kinds of edge-case implementations:

  • Chrome and Opera support all uses of calc, but prior to Chrome 38 / Opera 25, calculations with angle units won’t work.
  • Currently, Firefox supports calc used in length units and percentages only.
  • Android 4.4 only supports addition and subtraction operations, and earlier versions do not support calc at all. Chrome 38 on Android offers the same support as its fully-fledged desktop version.
  • Internet Explorer 9+ (desktop and mobile) offers good support of calc for length units. IE9 will crash if calc is used in association with the background-position property.

Thankfully, the vast majority of supportive browsers don’t require vendor prefixes.

calc can also be used to position color stops in CSS gradients and more; future articles will contain further examples.

Conclusion

Mathematical operations have been one of the features that preprocessors like have held over traditional CSS. While preprocessors still retain a number of advantages, functions like calc are narrowing the gap.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.