How much do you know about infinity in CSS?

w3cplus
11 min readMar 11, 2024

As we all know, many programming languages provide two special values to represent infinity and infinitesimal. For example, in JavaScript, we use the keyword infinity to represent infinity (∞), while -infinity represents infinitesimal (- ∞). However, what may surprise you is that these two concepts also exist in CSS - infinity ( infinity ) and infinitesimal ( -infinity ). When I first learned this information, it really surprised me. This discovery made me feel that CSS has become more magical and interesting.

So, today I will talk to you about the constant infinity (small) in CSS!

The story begins here…

When using CSS to define styles for elements, there are many scenarios where a very large value is used. For example:

  • Define the element in the z -axis level , for example, to a modal box will set z-index: 99999999 , so that always want the modal box in the z -axis of the highest layer, will not be covered by other elements
  • When making a capsule button , I habitually set a 999999rem value for the border-radius value
  • Sometimes, in order to hide an element, I habitually set a -9999999rem value to the left of an absolutely positioned element
  • Sometimes, in order to hide the text content, I habitually set a 999999rem value for the text-indent of the element
  • More….

Some time ago, a netizen mentioned a similar question, what is the maximum value of the top attribute of the positioning element? Can it be set to an infinite value? At first, I thought a value like 99999999vw was enough. But then I thought, this seems not rigorous enough.

To get a more rigorous answer, I found that the W3C CSS Values and Units Module Level 4 specification defines infinity and -infinity for CSS:

It is also supported by mainstream browsers :

In that case, let’s talk about it together as a new feature of CSS .

The article “ Illustrated CSS: Values and Units in CSS “ discusses values and units in CSS, but omits the constant values of CSS infinity and infinitesimal. In addition, if you are interested in new features of CSS, please read my book “ Modern CSS “!

The definition of infinity in CSS

The W3C specification describes infinity in CSS as follows :

When a calculation or a subtree of a calculation becomes infinite or NaN, representing it with a numeric value is no longer possible. To aid in serialization of these degenerate values, the following additional math constants are defined:

In short, when a computed value cannot be expressed numerically, it may become infinity, infinitesimal, or NaN . To serialize these degenerate values, the W3C's CSS Working Group defines the following additional mathematical constants:

  • infinity : a value that represents positive infinity (+ ∞), which represents the maximum possible value
  • -infinity : a value that represents negative infinity (− ∞), which represents the smallest possible value and is equivalent to the result of calc (-1 * infinity)
  • NaN (non-numeric): represents an undefined value

Note that all of these keywords belong to values of type <number> .

Similar to the general CSS keyword rules, these keywords are case-insensitive. Therefore, calc (InFiNiTy) is legal, but NaN must be serialized using the specified case. Next, we will focus on infinity in CSS without involving NaN .

Before we dive into this, there is an important ground rule: infinity ( infinity ) and infinity ( -infinity ) can only be used in calc() functions . Additionally, they are <number> value types, so to get the length value of infinity, you need to use an expression like calc(infinity * 1px).

Which calculated values in CSS will be infinite?

As mentioned earlier, positive infinity ( +∞ ) and negative infinity ( −∞ ) in CSS can be written directly using the mathematical constants infinity and -infinity . In addition, CSS can obtain these special values in other ways, such as the result of some calculations may produce infinity or infinitesimal.

  • Dividing a value by 0 will yield +∞ or −∞ , depending on standard notation rules. For example, calc(1 /0 ) will yield +∞ , and calc(-1 /0 ) will yield −∞ . This also applies to units. Therefore, you can use calc(1px/0) to get the same value as calc(infinity * 1px) .
  • Adding or subtracting any value ±∞ produces a corresponding infinity, e.g. calc(infinity + 1px)
  • Multiplying any value by ±∞ produces a corresponding infinity, for example calc(infinity * 1px)
  • Dividing any value by ±∞ produces zero
  • Mathematical functions have certain parameter combinations defined to produce infinity, for example, pow(0, -1) produces +∞

Note: The following rules for generating NaNoverride the above rules for generating infinity.

NaN(non-numeric) is the result of some operation that does not explicitly define a value. It can be written directly using the mathematical constant NaN, or it can be produced as the result of some computation:

  • Dividing zero by zero, dividing ±∞ by ±∞ , multiplying 0by ±∞ , adding +∞ to −∞ , or subtracting two infinities of the same sign yields NaN.
  • If there is a conflict, these rules override any other result. For example, 0/0 is NaN , not +∞ .
  • Some parameter combinations in mathematical functions are defined to produce NaN , for example, in sin(θ) , cos(θ) or tan(θ) functions, if θ is infinity , -infinity or NaN , the result returned is NaN ; in asin(θ) or acos(θ) functions, if θ is less than -1 or greater than 1 , the result returned is NaN .
  • Any operation with at least one NaN parameter produces NaN .
  • NaN does not escape top-level computation; it is reviewed as a zero value.

For example, calc(-5 * 0) produces an unsigned zero, i.e. the computation resolves to 0 , but since it is a top-level computation, it is reviewed as an unsigned zero. On the other hand, calc(1 / calc(-5 * 0)) produces −∞ , the same as calc(1 / (-5 * 0)) , i.e. the internal computation resolves to 0 , since it is not a top-level computation, it remains unchanged and is passed to the external calcto produce −∞ . If it is reviewed as an unsigned zero, it will produce +∞ .

Although there are so many ways to get infinity or infinitesimal in CSS, I still recommend using infinity or -infinity directly, which can express the intention more clearly, rather than putting a huge number (or numerical value) in the stylesheet to make the CSS clearer.

Infinite use cases in CSS

The most typical use case for CSS infinity should be z-index . If you set the value of z-index to infinity , you will get the maximum possible value and never have to worry about someone setting a value better than you. For example, in the following example, no matter how big the z-index value is set on the blue card, it cannot be used on the purple card with z-index: calc(infinity) set:

<div class="blue"></div>
<div class="purple"></div>
.blue {
--z-index: 999999999;
z-index: var(--z-index);
}
.purple {
z-index: calc(infinity);
}

No matter how many nines you type in the text box, you can't beat the level of the purple card on the z -axis:

Did you know that the upper limit of z-index is 2147483647 ? So when the z-index property value infinity encounters its upper limit value of 2147483647 , who will win? This is a question of meaning.

Normally, the infinity value of the z-index property and 2147483647 are considered the same value, but it cannot be determined that the value calculated by calc(infinity) is equal to 2147483647 . Let's write a test case to verify it.

Developers who understand CSS’s z-index property should know that to compare z-index , they must be in the same stacking environment. For example, in the following example, the two elements that apply z-index are not in the same stacking environment, and even if the value of the z-index property is set to infinity , it cannot win:

<div class="parent">
z-index: 2;
<div class="blue">z-index: infinity</div>
</div>
<div class="purple">z-index: 3</div>
.parent {
z-index: 2;

.blue {
z-index: calc(infinity);
}
}
.purple {
z-index: 3;
}

In the above example, many beginners think that z-index is invalid, but in fact, this is its basic rule. For a more detailed introduction to this, you can read the article " z-index invalidation and repair " in " Defensive CSS Insights ".

Defensive CSS Explanation “: How to make the UI you build or the CSS code you write more defensive (robust), to ensure that the restored UI can work under different conditions, without breaking the Web layout or Web UI, is a necessary skill for every professional Web front-end developer. This booklet starts from the perspective of “defensive” , it analyzes the precautions for writing CSS in various scenarios such as layout, UI effects, media objects, and interaction experience. You can regard it as a collection of CSS skills or CSS magic!

Continuing back to z-index . z-index There is another rule: "In the same stacking environment, if two elements specify the same z-index , it will be determined according to the order in which the elements appear in the HTML source code, that is, the first to appear wins. In other words, if our assumption is successful ( infinity is greater than 2147483647 ), it should be at the top regardless of the order of HTML.

Therefore, I prepared two stack contexts, as shown below, each with a different HTML order:

<div class="wrapper">
<div class="blue">z-index: 2147483647</div>
<div class="purple">z-index: calc(infinity)</div>
</div>
<div class="wrapper">
<div class="purple">z-index: calc(infinity)</div>
<div class="blue">z-index: 2147483647</div>
</div>
.wrapper {
z-index: 0;
}
.blue {
z-index: 2147483647;
}
.purple {
z-index: calc(infinity);
}

Compare .blue and .purple in the same stacking context. If the infinity of the z-index is the same as 2147483647 , the winner is determined in HTML order; if the infinity is greater than 2147483647 , the calc (infinity) element ( .purple ) will always be at the top of the z -axis is set.

The result has already told us the answer, the value of z-index is equal to infinity and 2147483647 . But this does not mean that infinity is equal to 2147483647 . It sounds a bit convoluted, even dizzy. You can try it, the result of calc(infinity - 2147483647) is the same as 2147483647 . This means that it has stopped at the z-index limit.

This case also shows that calc(infinity) may not always make z-index win, but its upper limit value of 2147483647 is not widely known, and it is also difficult to remember this string of values. That is to say, when one day you set the value of the z-index property to calc(infinity) and it does not win, you need to know the reason and make the right choice.

Another typical use case is capsule buttons or UI similar to capsule shapes.

In the case of buttons, I habitually set the border-radius to 999rem or 999vmax :

.pill {
border-radius: 999vmax;
}

By doing this, regardless of the height of the element, the effect of capsule UI can be achieved.

You can now replace 999vmax with calc (1px * infinity) :

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

This means that we don’t need to know the size of the element (rectangle box), and it will work normally. However, in some edge cases, we will encounter some strange behaviors. If you want to learn more about what happens in the border-radius case, you can read " What You Don't Know About Border-radius ".

Another similar use can be for hiding text or hidden elements. For example, code snippets that visually hide elements (visible only to screen readers).

.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
left: -9999vmax;
}

The code left: -9999vmax can be replaced with calc(-1px * infinity) :

.sr-only {
/* ... */
left: calc(-1px * infinity);
}

From a functional perspective, there is not much difference. The final effect is the same. But I think it does help make the code more readable because infinity conveys the true intention.

Finally, let’s take a look at a case related to animation. Assuming you have an element that needs to be removed from the screen, we often define animation as follows:

@keyframes slideOutRight {
to {
translate: 100vw;
}
}

.ani {
animation: slideOutRight 1s ease-out infinite;
}

If you try to replace the value of the translate property in @keyframes with calc(1px * infinity) , you'll see that the element immediately jumps to the end of the animation and stays there:

I can’t feel the animation effect at all. This makes sense. There is no incremental value on the way to infinity. A part of infinity is still infinity. Therefore, in every frame of the animation, the animation value is infinity.

In the article “ Web Animation Journey “, “ Key Tips for Improving Accessibility Animation “, it is emphasized that some of the web animation effects we created are not good for some groups. In order not to add unnecessary trouble to these users, we need to add code like the following to reduce the movement on the page:

@media (prefers-reduced-motion: reduce) {
*,
::before,
::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
background-attachment: initial !important;
scroll-behavior: auto !important;
transition-duration: 0s !important;
transition-delay: 0s !important;
}
}

With the constant infinity, you can add an easier way to reduce motion. You just set the values of transition-delay and animation-delay to infinity, and the animation on the page will never start playing:

@media (prefers-reduced-motion: reduce) {
*,
::before,
::after {
animation-delay: calc(1s * infinity) !important;
transition-delay: calc(1s * infinity) !important;
}
}

If you are interested in web animation, please read “ Web Animation Journey “:

Slam here direct: https://s.juejin.cn/ds/iFrsMxYy/

Summary

To summarize briefly, infinity in CSS is essentially an abbreviation for the maximum or minimum possible value in a specific situation. In some specific scenarios, they are very useful as they can help us achieve the desired effect and convey the true intention of CSS.

So far, the property value has been well supported, but whether to use it in your project is up to you. Finally, I want to emphasize again that Infinity can be used as a good indication of intent to make your CSS more readable , but this is certainly not mandatory.

--

--

w3cplus

Author of "Modern CSS," "Modern Web Layout," "In-Depth CSS Defense," and "A Journey into Web Animation!"