Chidume Nnamdi I'm a software engineer with 6+ years of experience. I've worked with different stacks ranging from WAMP, to MERN, to MEAN. My language of choice is JavaScript; frameworks are Angular and Nodejs.

CSS Reference Guide: calc()

2 min read 750

CSS Reference Guide: calc()

The CSS calc() function is used to evaluate simple arithmetic expressions in CSS.

Jump ahead:


The arithmetic expressions are addition, subtraction, division, and multiplication. These expressions follow a precedence order:

  • P – Parentheses
  • D – Division
  • M – Multiplication
  • A – Addition
  • S – Subtraction

Any parentheses in the expression are evaluated first, from left to right. Then the division operations are performed, then multiplication, addition, and, lastly, subtraction.

For example, we have this expression argument in calc:

calc(4px - (9px + 1px) / 5px * 9px)

See the Pen
css calc example
by Chidume David (@philipsz-davido)
on CodePen.

The parentheses (9px + 1px) are evaluated first, so we now have this:

4px - 10px / 5px * 9px

Next is the division op. 10px / 5px is evaluated to this:

4px - 2px * 9px

Then, the multiplication op is evaluated, 2px * 9px:

4px - 18px

Finally, the subtraction op is evaluated, 4px - 18px:

We made a custom demo for .
No really. Click here to check it out.

-14px

Value types

Not all value types in CSS are permissible in the calc function. Permitted values include:

  • <length>
  • <frequency>
  • <angle>
  • <time>
  • <percentage>
  • <number>
  • <integer>

Rules

There are certain rules that must be strictly followed when using the calc function.

1.) The RHS and LHS values of the addition and subtraction operators must be of the same unit type, or they can be a number and an integer.

  • 5px + 2 is invalid because the values are of different unit types. The first is a <length> type, while the second is a <number>.
  • 2px + 5vh is valid because both are of <length> unit types; operands in an expression may be of any <length> syntax value.
  • 3.4 - 4 is valid.

2.) The addition and the subtraction operator values must be whitespaced; failure would lead to incorrect parsing and evaluation of the expression.

  • 4px-5vh is invalid because there are no whitespaces before and after the - sign; the expression would be interpreted as 4px and a negative 5vh. To correct this, simply add spaces between them: 4px - 5vh.

3.) One of the values in a multiplication operation must be a <number> (or <integer>).

  • 4px * 5em is invalid because all of the values are of length unit types.
  • 4px * 5 is valid because the RHS value is a <number>.

N.B., the multiplication and division operators do not need whitespaces, unlike the addition and subtraction operators, e.g., 4*5px is valid. However, they are recommended for consistency.

4.) In the division operation, the RHS value must be a <number>.

  • 4px / 5em is invalid because the RHS value (5em) is a length unit. 4px / 5 is valid because the RHS value (5) is a <number>.
  • The unit type of its return value after an evaluation is determined by the LHS unit type. If the LHS unit type is and <integer>, then the return unit type is <number>.

5.) Any division that yields 0 is considered invalid.

  • 4rem/0 yields 0, so it is invalid.

6.) The calc function supports a maximum of 20 terms.

  • A term is <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer>. If this term number is exceeded, then the expression argument in the calc is invalid.

CSS variables and calc

CSS variables can be used in the calc expression arg. Note that CSS variables are used to store variables in selectors and use them anywhere in the styling with the var function.

::root {
    --width: 500px;
    --height: 900px;
}

div.burger {
    width: calc(10% - var(--width));
    height:  calc(12% + var(--height));
}

We have CSS vars --width and --height declared in the root scope, which are then retrieved using the var(...) function inside the calc function.

div.burger width length will be calc(10% - 500px). The var(--width) in the calc(10% - var(--width)) statement will be replaced with 500px. The height of div.burger will be calc(12% + 900px).


Examples of calc usage

calc comes in handy quite often during development. Let’s see where we can use calc instead of margin to set a gap on a button’s left and right sides.

.btn {
    padding: 6px 12px;
    margin-bottom: 0;
    font-weight: 400;
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    display: inline-block;
    background-image: none;

    border-radius: 3px;
    box-shadow: none;
    border: 1px solid transparent;
}

.btn-block {
    width: calc(100% - 20px);
}

The .btn.block selector stretches the button across its parent container with a 20px gap between the left and right sides.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

Which of these topics are you most interested in?
ReactVueAngularNew frameworks
Do you spend a lot of time reproducing errors in your apps?
YesNo
Which, if any, do you think would help you reproduce errors more effectively?
A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — .

Chidume Nnamdi I'm a software engineer with 6+ years of experience. I've worked with different stacks ranging from WAMP, to MERN, to MEAN. My language of choice is JavaScript; frameworks are Angular and Nodejs.

Leave a Reply