# Layout Math with CSS: Understanding calc

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>
<img src="fredvang.jpg" alt>
<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;
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
-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.