Buzz light year showing flying with a title showing css infinity and beyond
A cartoon skull with a hotpink hat on.7 min read

CSS Infinity Use Cases

css

CSS infinity (and -infinity!) solve some pretty specific problems elegantly, but can also just be plain fun to use.

Showing support for infinity, -infinity, NaN, pi, and e

Lets spur creative CSS juices with infinity and follow a couple use cases.

Basics and gotchas #

infinity and -infinity need to always be wrapped in calc().

If you want it to represent a dimension, it also needs to be multiplied by a unit like:

div {
  border-radius: calc(infinity * 1px);
  z-index: calc(infinity);
}

Not quite limited to calc() too, you can use it with other calc()-like scenarios like clamp(), min(), max(), etc, which we'll dig into a bit 🤘🏻

1. Circles and Pills #

Before infinity, I would have used scientific notation like 1e9px (which is 1000000000px) to create a "big enough" radius for circles and pills at any size.

But with infinity..!?

.radius-full {
  border-radius: calc(infinity * 1px);
}

2. Perma-state #

Setting duration calc(infinity * 1s) makes an animation/transition so long that it appears to be frozen ⛄️

Hover over those boxes and the duration will be pinned to happen over infinity seconds, sticking the state for the duration of the page's life.

I like how the duration of your hover is permanently made visible too. Visible millisecond duration via background color.

3. z-index #

Need to beat z-index: 999999999 or something?

.tippy-top-of-stacking-context {
  z-index: calc(infinity)
}

This will max out at the largest int a browser allows: 2147483647. Speaking of that number, you can see it by using counters like this:

.css-max-int {
  counter-reset: cssInt calc(infinity);

  &::after {
    content: counter(cssInt);
  }
}

See!

4. To infinity and beyond #

Use calc(infinity * 1px) to remove the floor or ceiling of a clamp.

div {
  inline-size: clamp(
    calc(-infinity * 1px), /* no floor */
    100%, 
    calc(infinity * 1px)   /* no ceiling */
  );
}

5. Freeze view transitions #

Make view transitions never complete.

::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
  animation-duration: calc(infinity * 1s);
}

The ::view-transition tree stays in the devtools DOM, giving you an opportunity to inspect or tweak.

You can also freeze and inspect animations using the Animations panel in devtools.

6. Responsive radius #

Another scenario where I would have reached for making a large number with scientific notation, is a responsive border radius.

.viewport-responsive-radius {
  border-radius: clamp(0px, (100vi - 100%) * infinity, 20px);
}

.container-responsive-radius {
  border-radius: clamp(0px, (100cqi - 100%) * infinity, 20px);
}

If the elements inline-size is less than 100vi, the radius will be 0. If it's greater than 100vi, the radius will be 20px.

There are a set of these available in Open Props.

7. Bools #

Clamp an arbitrary number down to exactly 0 or 1, then use it:

.flippy {
  --solo: clamp(0, (2 - sibling-count()) * infinity, 1);
  --crowded: clamp(0, (sibling-count() - 5) * infinity, 1);

  flex-grow: calc(1 - var(--solo));
  font-size: calc(1rem - var(--crowded) * 0.125rem);
}

One variable now can drive color, offset, opacity, gaps, whatever.

8. Backdrop #

You can use the spread feature of box-shadow to create a non-interactive backdrop:

.backdrop {
  box-shadow: 0 0 0 calc(infinity * 1px) #0005;
}

Paint past the "entire viewport".

Warning: This actually doesn't work!

Try on Codepen

Bramus explains it here

9. Scroll Trigger #

Trigger a scroll driven transition in, and never transition out.

.nav-title {
  timeline-trigger-activation-range-end: calc(infinity * 1px);
}

.product-title {
  animation: slide-and-fade 150ms ease both;
  animation-trigger: play-forwards play-backwards;
}

Though you'll see in the demo I use scroll 100% which is a specced way that feels closer to the intent I was going for, in that I wanted the range end to be the end of the scroll area.

Try it:

Also, just for funsies to share, here's the scroll driven version of the same navbar effect. Doesn't use infinity, but fun to try and compare scroll-triggered vs scroll-driven animation.

Thats all #

Hope you found that interesting!

Comment with your own creative uses of infinity?

17 comments #

71likes

plus Kevin, lowpoly.gg, vale.rocks and 44 more

19reposts
  • Roderick Gadellaa
  • Kevin Powell
  • Infixer
  • Ryan Mulligan
  • Manuel Matuzović
  • Alexander Lehner
  • Jean Pierre Kolb
  • GENKI
  • Agustin Capeletto
  • Jon Henshaw
  • Zacky Ma
  • Ufal Salman
  • poes ????????
  • blokche
  • stephansama
  • Daniel Schwarz
  • Rob

plus Kevin and 1 more

Join the conversation on

Nice! For inspecting view transition pseduo trees, you can also auto pause animations in the Chrome Devtools Animations panel.
James Stuckey WeberJames Stuckey Weber
I don't get the "Bools" use case. The "--active" is already set to be 0 or 1 (same as "--on") ????
CSS by T. AfifCSS by T. Afif
@argyleink “Before infinity, I would have used scientific notation like to create a ‘big enough’ radius for circles and pills at any size” WTF? You did that? You could do “border-radius: 100%” instead
Juan-Pablo ScalettiJuan-Pablo Scaletti
i'll rework the bools case ????
Adam ArgyleAdam Argyle
that's what i usually do, but this was a post on infinity. i'll add that clarification ????????
Adam ArgyleAdam Argyle
they can multiple infinity by 2 lol, but the same number gets clamped back you could… if you were evil, put the z-index in a keyframe and set the playhead so it's paused at that style. reach that maximum specificity spot
Adam ArgyleAdam Argyle
@jpscaletti border-radius 100% is relative! if you have anything other than a square, it gets wierd, and an absolute value ends up being more "reliable"
Adam ArgyleAdam Argyle
how's the rework?
Adam ArgyleAdam Argyle
@argyleink https://t.co/jq3WHew3Jo
Juan-Pablo ScalettiJuan-Pablo Scaletti
Ok I got the idea. It reminds me a few clamp() I was using as "toggles" between two random values which is similar to your idea.
CSS by T. AfifCSS by T. Afif
btw, now I would express them using sign() ex: --solo: max(sign(2 - sibling-count()), 0); but still the infinity trick can be handy in many situations.
CSS by T. AfifCSS by T. Afif
Very interesting! I'm going to start using `perspective: calc(infinity * 1px)` for isometric stuff.
Agustin CapelettoAgustin Capeletto
Nice! There’s also -infinity which can make a parallax element not move
Adam ArgyleAdam Argyle

CSS infinity use cases. @argyleink explores what calc(infinity * 1px) and -infinity can do beyond a hack for pill shapes. Use them for perfect circles, maxing out z-index at the integer limit, freezing animations with infinite durations to inspect view transitions in DevTools, removing floor and ceiling limits in clamp(), building boolean logic, and controlling scroll-driven animation ranges. Elegant, and plain fun to use. #css #animation

https://nerdy.dev/css-infinity-use-cases

animation css
Web StandardsWeb Standards

@argyleink It seems like the box-shadow trick doesn't actually work, unfortunately, even though it should be fully supported. It only works if I put a literal very large number.

I might be missing some edge that triggers infinity to work ????????‍♂️
Do you happen to have a live example please?

Marty ᗢMarty ᗢ
read an in depth exploration by @meyerweb.com at meyerweb.com/eric/thought...
Adam ArgyleAdam Argyle