fupio

Fupio is the easiest way to share online Learn more »

Join Fupio
Adam Argyle

Adam Argyle

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.

6. Bools#

Clamp an arbitrary number down to exactly 0 or 1, then use it:
.flippy {
  --active: 0;
  --on: clamp(0, var(--active) * infinity, 1);

  background: hsl(200 80% calc(50% - var(--on) * 20%));
  translate: 0 calc(var(--on) * -10px);

  &:active {
    --active: 1;
  }
}
One variable now can drive color, offset, opacity, gaps, whatever.
Flip with classes, media queries, etc, anything that can toggle a variable can become the moment a different style choice is made.

7. 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".

8. 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:
See the Pen by Adam Argyle (@argyleink) on CodePen.
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.
See the Pen by Adam Argyle (@argyleink) on CodePen.

Thats all#

Hope you found that interesting!
Comment with your own creative uses of infinity?
https://nerdy.dev/css-infinity-use-cases

Comments