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 eLets 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#
Beforeinfinity, 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 durationcalc(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 beatz-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#
Usecalc(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 ofbox-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
