The CSS Calculating Function Guide
CSS provides a special calc()
function for performing basic mathematical operations. This guide will cover almost everything you know about this very useful function.
Example:
.main-content { /* Subtract 80px from 100vh */ height: calc(100vh - 80px); }
This guide will dive into all aspects of this practical function.
calc()
is used for value
The calc()
function can only be used for values . The following example shows how we use it for values of multiple different properties:
.el { font-size: calc(3vw 2px); width: calc(100% - 20px); height: calc(100vh - 20px); padding: calc(1vw 5px); }
It can also be used only for part of the property, for example:
.el { margin: 10px calc(2vw 5px); border-radius: 15px calc(15px / 3) 4px 2px; transition: transform calc(1s - 120ms); }
It can even be part of another function that forms part of the property! For example, the following is an example of using calc()
in a gradient color scale:
.el { background: #1E88E5 linear-gradient( to bottom, #1E88E5, #1E88E5 calc(50% - 10px), #3949AB calc(50% 10px), #3949AB ); }
calc()
is used for length and other numerical values
Note that all the above examples are digitally based in nature. We will discuss the considerations for using numbers (because sometimes there is no need for units), but this is used for numerical calculations, not strings or other similar things.
.el { /* no! */ counter-reset: calc("My " "counter"); } .el::before { /* no! */ content: calc("Candyman " * 3); }
However, CSS has many units of length, and they all work with calc()
:
- px
- %
- em
- rem
- in
- mm
- cm
- pt
- pc
- ex
- ch
- vh
- vw
- vmin
- vmax
No unit numbers are acceptable. For example line-height: calc(1.2 * 1.2);
and angles such as transform: rotate(calc(10deg * 5));
.
You can also not perform any calculations, it still works:
.el { /* A little weird, but it can */ width: calc(20px); }
Not applicable for media queries
When calc()
is used correctly (the unit of length is used as the value of the attribute), unfortunately calc()
will not work when applied to media queries.
@media (max-width: 40rem) { /* Narrow or exactly 40rem */ } /* no! */ @media (min-width: calc(40rem 1px)) { /* Width above 40rem */ }
It would be cool if it could be implemented in the future, as you can perform mutually exclusive media queries in a rather logical way (as shown above).
Mixed units?
This is probably the most valuable feature of calc()
! Almost every example above has done this, but to emphasize this, there are different units mixed here:
/* Percentage units mixed with pixel units*/ width: calc(100% - 20px);
This means: as wide as the element width, minus 20 pixels.
In the case of fluid width, it is simply impossible to pre-calculate the value in pixels alone. In other words, you cannot preprocess calc()
with tools like Sass to try to complete polyfill. Of course, you don't need to do this either, as the browser supports it well. But the point is that when you mix units this way, you have to do this in the browser (in "runtime"), which is where most of the value of calc()
lies.
Here are some other examples of mixed units:
transform: rotate(calc(1turn 45deg)); animation-delay: calc(1s 15ms);
These may be preprocessed because the units they mix have nothing to do with anything determined at runtime.
Comparison with preprocessor mathematics
We just covered the most useful actions you can't preprocess calc()
can do. However, there is a little overlap. For example, Sass has math built in, so you can do the following:
$padding: 1rem; .el[data-padding="extra"] { padding: $padding 2rem; // Processing is 3rem; margin-bottom: $padding * 2; // Processed to 2rem; }
Even mathematical operations with units work there, adding together or multiplying values with the same units by unitsless numbers. But you can't mix units, and it has similar limitations to calc()
(e.g. multiplication and division must use unitless numbers).
Show math operations
Even if you don't use a feature that is unique to calc()
only, you can use it to "display your work" in CSS. For example, suppose you need to calculate the exact 1 ⁄ 7 of the element width…
.el { /* This is easier to understand*/ width: calc(100% / 7); /* is easier to understand than this*/ width: 14.2857142857%; }
This might work in some kind of self-created CSS API, for example:
[data-columns="7"] .col { width: calc(100% / 7); } [data-columns="6"] .col { width: calc(100% / 6); } [data-columns="5"] .col { width: calc(100% / 5); } [data-columns="4"] .col { width: calc(100% / 4); } [data-columns="3"] .col { width: calc(100% / 3); } [data-columns="2"] .col { width: calc(100% / 2); }
Mathematical operator of calc()
You have, -, * and /. But they are used differently.
Addition ( ) and subtraction (-) require that both numbers are length
.el { /* efficient? */ margin: calc(10px 10px); /* Invalid? */ margin: calc(10px 5); }
An invalid value invalidates the entire single declaration.
Division (/) requires that the second number has no unit
.el { /* efficient? */ margin: calc(30px / 3); /* Invalid? */ margin: calc(30px / 10px); /* Invalid? (cannot be divided by 0) */ margin: calc(30px / 0); }
Multiplication (*) requires that one of the numbers has no unit
.el { /* efficient? */ margin: calc(10px * 3); /* efficient? */ margin: calc(3 * 10px); /* Invalid? */ margin: calc(30px * 3px); }
Spaces are important
Well, that's true for addition and subtraction .
.el { /* efficient? */ font-size: calc(3vw 2px); /* Invalid? */ font-size: calc(3vw 2px); /* efficient? */ font-size: calc(3vw - 2px); /* Invalid? */ font-size: calc(3vw-2px); }
Negative numbers are OK (e.g. calc(5vw - -5px)
), but this is an example where spaces not only require but also help.
Tab Atkins tells me that the reason why spaces are needed around and - is actually a parsing problem. I can't say I understand it completely, but for example, 2px-3px
is parsed into the number "2" and the unit "px-3px", which doesn't do anything good for anyone, and there are other issues like being consumed by "number grammar". I thought spaces had to be related to the --- syntax of custom properties, but not!
Multiplication and division do not require spaces around operators. But I think the good general advice is to include spaces for readability and other operators' muscle memory.
The spaces around the outside do not matter. You can even make a line break if you like:
.el { /* efficient? */ width: calc( 100% / 3 ); }
But be aware of this: there is no space between calc()
and open brackets.
.el { /* Invalid? */ width: calc (100% / 3); }
Nested calc(calc());
You can do this, but it's never necessary. It's the same as not using calc()
part but using only the extra set of brackets. For example:
.el { width: calc( calc(100% / 3) - calc(1rem * 2) ); }
You don't need these inside calc()
, because brackets can work separately:
.el { width: calc( (100% / 3) - (1rem * 2) ); }
In this case, the "order of operations" can help us even without brackets. That is, division and multiplication occur first (before addition and subtraction), so there is no need for brackets at all. It can be written like this:
.el { width: calc(100% / 3 - 1rem * 2); }
But feel free to use brackets if you feel it increases clarity. If the order of operations is bad for you (for example, you do need to add or subtract first), you need brackets.
.el { /* this*/ width: calc(100% 2rem / 2); /* Very different from this*/ width: calc((100% 2rem) / 2); }
CSS custom properties and calc()
?
Apart from the amazing ability of calc()
to mix units, the next best thing about calc()
is to use it with custom properties. Custom properties can have values that you subsequently use in your calculations:
html { --spacing: 10px; } .module { padding: calc(var(--spacing) * 2); }
I believe you can imagine a CSS setup where a lot of configurations are done at the top by setting a bunch of CSS custom properties and then letting the rest of the CSS use them as needed.
Custom properties can also be referenced to each other. Here is an example using some math operations (note that calc()
function is missing first), and then applied later. (It must eventually be inside calc()
.)
html { --spacing: 10px; --spacing-L: var(--spacing) * 2; --spacing-XL: var(--spacing) * 3; } .module[data-spacing="XL"] { padding: calc(var(--spacing-XL)); }
You may not like that because you need to remember and then use calc()
for that property, but this is possible and can be interesting from a readability standpoint.
Custom properties can come from HTML, which is sometimes a very cool and useful thing. (See Splitting.js How to add indexes to words/chars as examples.)
<div style="--index: 1;"> ...</div> <div style="--index: 2;"> ...</div> <div style="--index: 3;"> ...</div>
div { /* Index value comes from HTML (with fallback)*/ animation-delay: calc(var(--index, 1) * 0.2s); }
Add units later
If you are in a situation where it is easier to store unitless numbers or use unitless numbers for math in advance, you can always wait until the number is applied before adding units by multiplying by 1 and units .
html { --importantNumber: 2; } .el { /* The number remains at 2, but now there are units*/ padding: calc(var(--importantNumber) * 1rem); }
Processing colors
Color formats such as RGB and HSL have numbers that you can process with calc()
. For example, set some basic HSL values and then change them to form a system you created yourself (example):
html { --H: 100; --S: 100%; --L: 50%; } .el { background: hsl( calc(var(--H) 20), calc(var(--S) - 10%), calc(var(--L) 30%) ) }
You cannot combine calc()
and attr()
The attr()
function in CSS looks attractive, just like you can extract attribute values from HTML and use them. but……
<div data-color="red"> ...</div>
div { /* no*/ color: attr(data-color); }
Unfortunately, there is no "type" in action here, so attr()
is only used for strings used with content
attribute. This means this works:
div::before { content: attr(data-color); }
I mentioned this because it can be tempting to try to extract numbers in this way for calculations, for example:
<div data-columns="7" data-gap="2"> ...</div>
.grid { display: grid; /* Neither of these works*/ grid-template-columns: repeat(attr(data-columns), 1fr); grid-gap: calc(1rem * attr(data-gap)); }
Fortunately, this doesn't matter, because custom properties in HTML are just as useful or more useful!
<div style="--columns: 7; --gap: 2rem;"> ...</div>
.grid { display: grid; /* Can! */ grid-template-columns: repeat(var(--columns), 1fr); grid-gap: calc(var(--gap)); }
Browser Tools
The browser DevTools tends to show you calc()
you created in a stylesheet.
If you need to find out the calculated value, there is a "Computation" tab (in all browsers DevTools, at least those I know) that will show you it.
Browser support
This browser supports data from Caniuse, which contains more details. The number indicates that the browser supports this feature in this version and later.
desktop
Mobile/Tablet PC
If you do need to support very old versions (such as IE 8 or Firefox 3.6), the usual trick is to add another property or value before using the property or value of calc()
:
.el { width: 92%; /* fallback*/ width: calc(100% - 2rem); }
There are also some known issues calc()
, but they are all for older browsers. Can I use… 13 are listed. Here are some:
- Firefox
- IE 9-11
box-shadow
property is not rendered when usingcalc()
as any value. - Neither IE 9-11 nor Edge support
width: calc()
for table cells.
Use Cases
I asked some CSS developers how long they last used calc()
so that we can have a good idea of how others use it in their daily work here.
I use it to create a full-screen utility class:
.full-bleed { width: 100vw; margin-left: calc(50% - 50vw); }
I thinkcalc()
belongs to one of my three CSS items.
I use it to make room for sticky footers.
I use it to set some fluid type/dynamic typography… font size calculated based on minimum, maximum and viewport unit rate of change. Not only the font size, but also the line height.
If you are using calc()
as part of a fluid type case involving viewport units, etc., make sure to include units that use rem or em so that the user can still control the font up or down adjustments by zooming in or out as needed.
One I really like is having a "Content Width" custom property and then using it to create the spacing I need, for example margins:
.margin { width: calc( (100vw - var(--content-width)) / 2); }
I use it to create a cross-browser initials sink component. This is part:
.drop-cap { --drop-cap-lines: 3; font-size: calc(1em * var(--drop-cap-lines) * var(--body-line-height)); }
I use it to make some images overflow their container on the article page.
I use it to correctly place the visualization on the page by combining it with padding and vw/vh units.
I use it to overcome the limitations of
background-position
, but especially the limitations of positioning color markers in gradients. For example, "stop is 0.75em from the bottom".
Other tips
- A two-column grid that can be converted to a single column without media queries
- A hero component similar to aspect ratio
- Forced high contrast color
- Helps coordinates of clip paths based on percentage
The output maintains the original image format and placement as requested. The text has been paraphrased and reorganized for originality while retaining the core meaning.
The above is the detailed content of The CSS Calculating Function Guide. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











I see Google Fonts rolled out a new design (Tweet). Compared to the last big redesign, this feels much more iterative. I can barely tell the difference

Have you ever needed a countdown timer on a project? For something like that, it might be natural to reach for a plugin, but it’s actually a lot more

Everything you ever wanted to know about data attributes in HTML, CSS, and JavaScript.

When the number of elements is not fixed, how to select the first child element of the specified class name through CSS. When processing HTML structure, you often encounter different elements...

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...

At the start of a new project, Sass compilation happens in the blink of an eye. This feels great, especially when it’s paired with Browsersync, which reloads

How to implement Windows-like in front-end development...

Tartan is a patterned cloth that’s typically associated with Scotland, particularly their fashionable kilts. On tartanify.com, we gathered over 5,000 tartan
