The New CSS Math: pow(), sqrt(), and exponential friends

CSS added many new Math functions to supplement the old favorites (such as calc()). They all ultimately represent a numeric value, but the nuance in how they work is not always clear from the start. As of February 2024, these CSS functions are available in the latest Edge, Chrome, Safari and Firefox browsers.

The basics of CSS pow() 

Powers in math allow us to specify how many times to multiply a number by itself.

Now available in CSS, the pow() function takes two parameters: our initial number and the exponent value to apply to it.

line-height: pow(3, 2); /* 9 */
line-height: pow(3, 3); /* 27 */
line-height: pow(2, 4); /* 16 */

This mirrors the functionality long available in JavaScript via Math.pow().

console.log(Math.pow(3, 2)); // 3 * 3 = 9
console.log(Math.pow(3, 3)); // 3 * 3 * 3 = 27
console.log(Math.pow(2, 4)); // 2 * 2 * 2 * 2 = 16

Unlike many of the other new CSS Math Functions, pow() only works with raw numbers. You cannot apply units inside the function, so in order to get a unit you will need to use pow() in combination with calc(),

font-size: calc(1rem * pow(2, 2)); /* 1rem * 4 = 4rem */
rotate: calc(5deg * pow(2, 5)); /* 5deg * 32 = 160deg */

But what about the roots? 

Just like we have Math.sqrt() in JavaScript, we now have sqrt() in CSS to find the square root of a number. It takes one parameter, and like pow() it works with just numbers (not lengths, percentages, and other types that have units)

line-height: sqrt(4); /* 2 */
line-height: sqrt(9); /* 3 */
line-height: sqrt(12); /* about 3.4641 */

If you want to take a root that is not square (such as cube root, etc.), you will still need to use pow(). If you use a fraction as your exponent, you get a root (such as 1/3 for a cube root).

line-height: pow(4, .5); /* square root of 4: 2 */
line-height: pow(4, 1/2); /* square root of 4: 2 */
line-height: pow(27, 1/3); /* cube root of 27: 3 */
line-height: pow(2, 3/2); /* cubed and then a square root: about 2.8284 */

Using these new math functions in practice 

As with many of these new math functions, how you will use them in daily work is not always clear.

In the spec, an example is shown to use pow() for font sizes and a modular scale. With this each heading, for example, can be in relation to the same root size. While use of pow() is not strictly needed here as values could be calculated and then pasted in, readability is helped for maintenance as the intent is clearer when showing the pow().

See the Pen CSS pow() and Modular Scale by Dan Wilson (@danwilson) on CodePen.

Or you can think a bit outside the box.

Combined with @property and Custom Properties, we can create a linear animation that feels like it has easing. That is, the animation should proceed equally over time, but by using exponents our animation feels like it is starting slow and then speeding up.

We can animate a variable from 1 to 10 with a linear timing function. Then we apply that variable as the exponent of a pow() for some transform (like a rotation or translation). The animation will be from 1 to 10 evenly but the value of the transform will increase exponentially, speeding up the resulting visual motion.

See the Pen exponential animation easing by Dan Wilson (@danwilson) on CodePen.

Other exponential functions 

There are three other functions related to exponents to know about.

e to a power with exp() 

The exp() function takes one parameter, representing the exponent to apply to the mathematical constant e. So exp(3) is equivalent to pow(e, 3), and like pow() it also does not allow units. This behaves similarly to Math.exp() in JavaScript.

Logarithms with log() 

Relatedly, log() takes two parameters (the second is optional) and represents logarithms.

In JavaScript Math.log only takes one parameter, and it represents the natural logarithm of the number passed as the parameter. The base of this logarithm is e.

The optional second parameter that CSS adds for log() allows us to change the base from e to a new number.

opacity: log(2); /* log 2 for base e = .693147 */
opacity: log(2, 10); /* log 2 for base 10 = .30103 */

JavaScript does not have a second parameter, so CSS adds the base change as a convenience. The equivalent of CSS log(number, base) can be achieved in JavaScript as Math.log(number) / Math.log(base).

The square root of sum of squares with hypot() 

It’s a lot of words, but it is a fun, niche function.

In geometry with a right triangle, you can find the length of the hypotenuse (the side opposite the right angle) by the following process

  1. Square both the other sides
  2. Add these values together
  3. Square root the sum from the previous step

See the Pen Hypotenuse on Resize by Dan Wilson (@danwilson) on CodePen.

So with CSS the hypot() function (and in JavaScript with the Math.hypot() method), we can pass in an arbitrary amount of parameters. The function will then square all the parameters, add them together, and take the square root.

animation-iteration-count: hypot(2); /* 2 */
animation-iteration-count: hypot(3, 4); /* 5 = sqrt(9 + 16) = sqrt(25) */
line-height: hypot(1, 2, 3, 4); /* ~5.4772 = sqrt(1 + 4 + 9 + 16) = sqrt(30) */
line-height: hypot(-2); /* 2 */
width: hypot(30px, 40px); /* 50px = sqrt(900px + 1600px) = sqrt(2500px) */

This is the one function discussed in this article that does allow units as long as all items are of the same type.

translate: hypot(3px, 4px); /* 5px = sqrt(9px + 16px) = sqrt(25px) */
translate: hypot(3px, .25rem); /* 5px = sqrt(9px + 16px) = sqrt(25px) */
rotate: hypot(3deg, 4deg); /* 5deg = sqrt(9deg + 16deg) = sqrt(25deg) */