The New CSS Math: pi and other constants
CSS added many new Math constants to be used inside Math functions (such as calc()
). The new constants are pi
, e
, infinity
, -infinity
, and NaN
. As of February 2024, these CSS constants are available in the latest Edge, Chrome, Safari and Firefox browsers.
The basics of CSS pi
When used inside a Math function (calc()
, pow()
, round()
, etc.), pi
equates to the mathematical constant value pi (π, approximately 3.142). Just as we are able to in JavaScript via Math.pi
we can use the constant directly instead of using an approximated value.
width: calc(pi * 3px); /* ~9.42px */
width: calc(pi * 1rad); /* ~3.14rad = 180deg */
line-height: calc(pi * .5); /* ~1.57 */
It’s important to note that none of these mathematical constants can be used outside of a math function. When used without a math function they will be a generic string. That could still result in valid CSS (such as an animation named pi
used with animation-name: pi
), but more than likely it will be invalid if you are trying to use it as a number. If you want it to equate to the number pi, you’ll need it inside a math function.
line-height: pi; /* invalid */
animation-name: pi; /* valid as string, will use keyframes defined as pi */
animation-iteration-count: pi; /* invalid */
animation-iteration-count: calc(pi); /* valid, ~3.14 */
animation-iteration-count: round(pi, 1); /* valid, 3 */
line-height: pow(pi, 2); /* valid, ~9.87 */
Some use cases with pi
The benefits of using pi
appear to be more about clarity of intention than specific mathematical precision. When used in combination with pixels, I would expect pi to represent approximately 3.1415927px. Using getComputedStyle()
in the latest versions of Firefox, Safari, and Chrome (February 2024) gave mildly different calculations when used.
Specified calc() | Firefox | Safari | Chrome |
---|---|---|---|
pi * 1px | 3.13333px | 3.140625px | 3.14062px |
pi * 10px | 31.4167px | 31.40625px | 31.4062px |
pi * 100px | 314.167px | 314.15625px | 314.156px |
pi * 100000px | 314159px | 314159.25px | 314159px |
If you are familiar with using radians in defining angles in mathematical contexts, the introduction of the pi
constant brings more clarity to CSS. Previously, I never found myself reaching for radians when specifying angles in CSS, because they are based around pi. One complete rotation is 2 * pi radians
, and previously we had to specify that in CSS as 6.284rad
or a similar approximation. Radians are not always intuitive when you have to specify values in only a decimal number.
The following are all equivalent ways to define halfway around for a rotation.
rotate: 180deg;
rotate: .5turn;
rotate: calc(pi * 1rad);
rotate: 3.142rad;
We can also use pi
to simplify calculating lengths of circles and curves. The total length of a circle’s stroke can be calculated in CSS directly since the circumference of a circle is defined as 2 * pi * radius
, so we can use the raw length for a stroke dash animation.
See the Pen DashOffset animation with CSS pi by Dan Wilson (@danwilson) on CodePen.
The basics of CSS infinity
There are two usable constants to represent Infinity which are infinity
and its opposite of -infinity
. Both effectively represent the largest possible value, as a positive or negative, respectively.
z-index: calc(infinity);
z-index: pow(infinity, 1);
left: calc(-infinity * 1px);
opacity: round(down, infinity, infinity); /* weird, but valid */
Again, one of the biggest benefits of using infinity
is clarity of intent. If you are trying to say you want the highest possible pixel value to ensure it is pushed off screen, infinity
might be a clearer (and safer) choice than specifying an arbitrary value you assume is the largest reasonable value.
Depending on the browser and the type calculated, infinity
can compute to fairly different values, but still consistently large. For further reading, Will Boyd discusses some interesting uses cases and computed value fun for infinity
.
The basics of CSS e
To represent the mathematical constant for Euler’s number, we now have... e
! This constant is used with logarithms and exponential growth in mathematics, and it equates to approximately 2.71828.
The same rule applies here as for the other constants: it must be used in a function like calc()
.
opacity: calc(e / 3); /* ~.906 */
line-height: pow(e, 2); /* ~7.389; */
font-size: calc(e * 1rem); /* ~2.71828rem */
opacity: e; /* invalid */
The basics of CSS NaN
The last numeric constant added to CSS is NaN
, everyone’s favorite not-a-number representation. As with most of these Math additions to CSS, they allow for correlation to the existing JavaScript Math concepts, and NaN
is no different. Spec-wise, it allows a representation for values that do not exist for certain function usage. For example, finding a remainder with a zero (such as rem(3, 0)
) will result in NaN
because dividing by zero is not mathematically possible. Offering this in the spec gives a way to both map to the JavaScript version of NaN
and represent situations where a CSS calculation does not result in a number in a clear cut manner.
In practice, however, CSS has to resolve to some value. If you try to find the computed value of scenarios with NaN
, used either as a direct value or in a calculation that resolves to it, you will find a valid value ultimately applied.
For example for an element with the following specific CSS
#element {
opacity: 1;
opacity: calc(NaN);
}
In each of Firefox, Safari, and Chrome, the second opacity declaration gets applied as it is a valid value. In this case, the computed value applied is 0
. Similarly, if the second opacity had been defined as opacity: rem(9, 0)
(which the spec says should resolve to NaN
whenever the second parameter is zero) the computed value is still 0
since rem(9, 0)
and calc(NaN)
are both effectively the same NaN
.
Attempting width: calc(NaN * 1px)
results in a computed value of 0px
. A z-index: calc(NaN)
is also 0
... as is z-index: calc(NaN * infinity)
.
But now you’re just asking for trouble.