Smart CSS layouts with Calc()

Calculator by jm2c

A few weeks ago I wrote about the Traditional Box Model and the ‘box-sizing’ CSS property, which, in essence, allowed you to easily create two adjacent boxes with a width of 50% and any amount of padding, because padding was included in the width. In this article I will talk about a different method of achieving this with the help of the ‘calc()’ expression.


The Basics

The calc() expression has been developed to make the developing of layouts in CSS simpler for the developer, it doesn’t look any different on screen, it just means the web browser works out the correct size instead of you.

One reason that calc() is not mainstream as yet is it’s somewhat patchy browser support. It’s not available in IE8 and below, it has just arrived in Chrome (with prefix), Firefox has supported it for a while (with prefix) and calc() won’t work with the Android Browser or Opera. It’s for this reason that developers should be cautious when using it just yet.

Update 20/12/12: calc() is now supported in Firefox without prefix and works with IE9+.


Syntax

css-property: calc( measurement1 operator measurement2 ); 

The calc() expression can, according to the W3C specification, be applied to any value of length, frequency, angle, time or number. So this includes width, height, padding margin etc.

The arithmetic operators at your disposal include:

  • + Addition
  • - Subtraction
  • * Multiplication
  • / Division

Another important thing to mention is that any number of measurements can be used within the same calc() function and all with different measurement types (e.g. mixing percentages, pixels and ems is fine).


With Prefix Support

.sample-box
{
    width: 200px; /* Fallback if Unsupported */
    width: -webkit-calc(50% - 20px); /* Chrome 19+ & Safari */
    width: -moz-calc(50% - 20px); /* Firefox v4-15 */
    width: calc(50% - 20px);
}

Many browsers still only support calc() with prefixes so it’s necessary to include these for wider support. Debatably, it might be worth including the Opera prefix (-o-) as well, even though it’s no supported it might be in the future and could potentially save code maintenance.


Demo

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent luctus commodo ante sed molestie. Nam vitae felis odio, in iaculis sem. Phasellus sed nisi et lorem posuere iaculis quis sit amet risus. Morbi ipsum leo, eleifend id condimentum non, varius in est. Nunc a mauris quam.
Maecenas sed odio felis, quis gravida est. Vestibulum massa magna, sodales quis congue quis, iaculis quis turpis. Nullam lectus leo, tempus dignissim placerat in, pretium et diam. Aliquam ullamcorper dolor eget metus dignissim pellentesque.
.sample-box
{
    width: 200px;
    /* width = (half of 100% - two sides of padding - two borders) */
    width: -webkit-calc(50% - 30px - 2px);
    width: -moz-calc(50% - 30px - 2px);
    width: calc(50% - 30px - 2px);

    float: left;
    padding: 15px;
    font-size: 12px;
    text-align: justify;
    border: 1px solid #999;
}

Conclusion

So there we have it, a brilliant addition to the CSS language. The calc() function just makes the life of developers a little easier – in theory at least. As of yet, it hasn’t reached a dominant browser adoption level so, depending on the website in question, it shouldn’t be depended upon. According to html5please.com (a community driven website dedicated to advice on which new web features to use), the calc() function should be avoided for the time being in production websites and I think this is a fair call for the moment.

Do you use calc() in your stylesheets? Let us know in the comments.


Cover Photo by jm2c

5 Responses to Smart CSS layouts with Calc()

  1. Ayanami says:

    I actually used -webkit-calc() once, in a project that was bound to WebKit rendering engine, but with a script-based polyfill it would be useful for general purpose web apps or sites.

    Nice post btw.

  2. Anthony says:

    I have used calc() but that does not work in Safari 5.1.7 (the latest version as of today). Do you know of any way to make it work? Thanks in advance.

Leave a Reply