title: Playing with Infinity in CSS
url: https://codersblock.com/blog/playing-with-infinity-in-css/
hash_url: 1f4e359d10
archive_date: 2024-03-06
og_image: https://codersblock.com/assets/images/blog/infinity-light-streaks.png
description: CSS has an infinity constant. When I first learned about this, my brain lit up with all kinds of absurd possibilities. Let’s discuss! There might even be some…
favicon: https://codersblock.com/favicon-32x32.png
language: en_US
CSS has an infinity
constant. When I first learned about this, my brain lit up with all kinds of absurd possibilities. Let’s discuss! There might even be some practical use cases.
No promises, though.
Before we get into things, there’s one important ground rule: infinity
can only be used inside a calc()
statement. Alright, let’s go.
Have you ever needed an element to appear on top of everything else, but the constantly escalating z-index
arms race forces you to resort to higher and higher z-index
values?
End the battle. Use infinity
to get the highest possible z-index
and win forever.
In the demo below, there is no possible z-index
value for the blue card that will put it above the purple card with z-index: calc(infinity)
. Give it a try!
See the Pen Unbeatable z-index by Will Boyd (@lonekorean) on CodePen.
What happens when you create a <div>
with a width
and height
of infinity
pixels?
.big {
width: calc(infinity * 1px);
height: calc(infinity * 1px);
}
Notice we’re multiplying infinity
by 1px
to turn it into a pixel length.
Here’s a demo showing the result, with some extra output so we can get a better idea of what’s happening in the browser.
See the Pen The Largest Possible Element by Will Boyd (@lonekorean) on CodePen.
The values under getComputedStyle()
are what the CSS properties resolve to. The values under getBoundingRect()
reflect the actual size of the rendered <div>
in the viewport. Here’s the code snippet.
const computed = window.getComputedStyle(bigEl);
const computedWidth = computed.getPropertyValue('width');
const computedHeight = computed.getPropertyValue('height');
const rect = bigEl.getBoundingClientRect();
const rectWidth = rect.width + 'px';
const rectHeight = rect.height + 'px';
First of all, infinity
in CSS is not actually infinite. It’s just a really big number. My disappointment is immeasurable, unlike infinity
in CSS.
On my machine (Windows desktop using Chrome) the total area of the <div>
in the demo is 33,554,428px squared, which works out to roughly 79km2. Not bad! But also not infinite.
Notice I said “on my machine” in that last paragraph. Although infinity
is supported in all major browsers, the value it resolves to can be inconsistent across browsers and operating systems.
Some examples from the demo above:
width
and height
, half what I get on Windows.width
of 1.78957e+7px when using getComputedStyle()
and 8,947,849px when using getBoundingRect()
.height: calc(infinity * 1px)
— just ignores it. But setting height: 17895697px
(the largest CSS length Firefox allows) works. I don’t know why Firefox doesn’t resolve height
to that value like it seems to do with width
.On top of all that, infinity
can resolve to different values based on which CSS property you’re using it with. Remember that z-index
example from earlier? The value of infinity
there was 2,147,483,647 — consistent across all browsers I tested, but different from the various width
and height
values we just saw.
All these wacky values for infinity
are not randomly picked, of course — they are a result of how the numbers are being stored. For example, 2,147,483,647 is 231 - 1, the largest possible value for a signed 32-bit integer.
What happens if you try to animate an element to infinity
, like this?
.interstellar {
animation: go 10s;
}
@keyframes go {
to { translate: calc(infinity * 1px); }
}
Turns out the element will immediately jump to the end of the animation and stay there for the duration. So in this case, the element stays as far off to the right as the browser can handle for the entire 10 seconds.
Makes sense. There are no incremental values on the way to infinity. A fraction of infinity is still infinity. So for every frame of the animation, the animated value is infinity.
What happens when you set an infinite animation-delay
?
.interstellar {
animation-delay: calc(infinity * 1s);
}
You can probably guess. The animation never starts.
Would you ever actually want to use infinity
in your CSS? Maybe! Sometimes you just need a huge value (whatever it is) and infinity
can give that to you.
For example, you can make a pill shape by using border-radius
with a (non-percentage) length value. Using a value bigger than you need won’t change the shape and is actually a good idea in case the element changes size.
div {
border-radius: calc(infinity * 1px);
}
See the Pen Pill Shape by Will Boyd (@lonekorean) on CodePen.
Another possible use is with a common snippet of CSS used to make content “screen reader only” by positioning it way off the side of the page.
.screen-reader-only {
position: absolute;
left: calc(infinity * -1px);
}
But is infinity
really any better than some arbitrarily big value like 9999px
? Functionally, no. Same end result. But I think it does help make code more self-documenting, because infinity
conveys intent. It expresses that it’s all about the magnitude, not a specific magic number.
Dividing by zero will give you infinity
. In other words, calc(1 / 0)
and calc(infinity)
are the same. This also works with units. So you can do something like calc(1px / 0)
and get the same value as calc(infinity * 1px)
.
Good to know, but I’d still use infinity
directly to make the CSS more obvious.
There’s also a -infinity
constant that gives you the smallest possible value. No surprises here, it’s the same as multiplying infinity
by -1
.
To recap, the main thing to know about CSS infinity
is that it’s essentially shorthand for the largest possible value in a particular situation. This value can and will change between browsers, operating systems, and CSS properties.
Whether or not to use infinity
is up to you. Browser support is pretty good, and infinity
can be a good indicator of intention that makes your CSS more readable, but it’s certainly not mandatory.