The min(), max(), and clamp() CSS functions can revolutionize web layouts, but they can also make CSS much more difficult to reason about.

I recently had an opportunity to redesign a site, so I thought I would get a handle on the min(), max(), and clamp() CSS functions that are now starting to be widely enough implemented to be useful.

In my estimation, these functions have the potential to revolutionize web layouts, but they can also make CSS much more difficult to reason about if used to their full potential.

What are these functions?

We’ll refer to MDN for their definitions.

  • min(): Lets you set the smallest (most negative) value from a list of comma-separated expressions as the value of a CSS property value
  • max(): Lets you set the largest (most positive) value from a list of comma-separated expressions as the value of a CSS property value
  • clamp(): Clamps a value between an upper and lower bound. clamp() enables selecting a middle value within a range of values between a defined minimum and maximum. It takes three parameters: a minimum value, a preferred value, and a maximum allowed value

Another interesting note is that you can do math inside the functions without using calc. So, instead of min(calc(5vw + 5px), 50px);, you could just do min(5vw + 5px, 50px);. Of course, you could also have done your calculation inside a variable and just used that variable.

One thing that might be confusing is the naming. min() returns the minimum value from its list of values, and max() returns its maximum value, as you might expect. But what would happen if I were to do the following (a truly ridiculous usage for purpose of the example):

width: min(1px,200px,300px);

Of course, 1px is returned, meaning that the output of min function sets the maximum value of that width to be 1px.

As the W3C spec for CSS Values and Units Module Level 4 says:

An occasional point of confusion when using min()/max() is that you use max() to impose a minimum value on something (that is, properties like min-width effectively use max()), and min() to impose a maximum value on something; it’s easy to accidentally reach for the opposite function and try to use min() to add a minimum size. Using clamp() can make the code read more naturally, as the value is nestled between its minimum and maximum.

Here is an example with three divs, two showing min() value outputs and one showing max() value outputs to set the width:

Each div has as its text content the actual min() or max() function that is being used to set its width, so you can easily see the effect.

Each of these functions can be used anywhere a length, frequency, angle, time, percentage, number, or integer can be used. Obviously, this means that they can take as an input any of the units that can be used with these types of values. So, for example, you could have something like the following:

transform: rotate(min(45deg, .15turn));

Using these functions in unexpected ways

Of course, it is immediately obvious how you would use these functions in properties like width or functions like calc() (or, if not immediately obvious how to use them, at least immediately obvious that they could be used there). But there are numerous other ways they can be used that might not be readily apparent.

The primary lesson to take from this section is that since these functions work on units, you can take as an input any function that returns a — such as calc() — or use them inside any function that expects a unit. So as our first example, let’s use them in the very-not-obvious HSL function.

Use with the HSL function

HSL stands for hue, saturation, lightness and is a function added in CSS 3. You can refer to this post for a refresher on HSL.

The following example will not appear to be particularly useful at first, but take a look at how you could use min and max inside the HSL function:

hsl(min( 180, 190, 150), max(75%, 50%; 100%), 50%)

This doesn’t give you anything that you couldn’t get by simply doing the calculation in your head and writing:

hsl(150, 100%, 50%)

In this case, you know what all the values would be. CSS variables make these functions much more useful in cases like this.

Using math and HSL with CSS variables

CSS variables can be overwritten by media queries, loading specific CSS in the context of where you are on the site, or having the variable value changed by JavaScript.

Thus, once you can do things like this:

hsl(
   min(
    var(--extreme-hue),
    var(--base-hue)
   ),
   max(
    var(--base-saturation),
      var(--region-saturation)
   ),
 50%);

It opens up the door to having more meaningful and powerful calculations. (Please note that in the context of a site or application, variable names may be more reflective of usage; here they are just meant to indicate a methodology.)

Here is an example:

And here is an example of overriding the CSS variable value inside a media query:

As I said, you can also override the CSS variable with JavaScript. Here’s a silly example changing the variables randomly in a two-second interval:

Functions that can use min(), max(), and clamp()

As I’ve demonstrated, because of the existence of CSS variables, even the functions you might consider unlikely to benefit from min(), max(), or clamp() can still use them.

So, here is a list of functions in which you could use the math functions, although you might not normally expect to (functions where you might expect to use them, like calc(), have been left out). The list is divided into types of functions for ease of comprehension:

Color functions

These functions will output a filter or work on an image’s color scheme.

Shape functions

These functions will create a shape (an image) or output a transformation:

There are, of course, other functions available, but some of these are not usable in any way I can think of with these functions, no matter how creative you try to be — or, at the time of this writing, they are not supported across the most popular platforms and, thus, are unlikely to be worth using.

Unexpected ways in which these functions don’t work — yet

As noted before, these functions can accept anything that is a number or a calculable value, like the length of a variable, as an input. Furthermore, they can take as inputs such things as variables, where you might have saved the result of a calculation, a number, or another value.

Many different CSS properties have special keywords that in the end will return a value that is a length or a percentage or a number — that is to say, something that would be potentially usable by one of these functions.

As an example, width has the following special keywords:

  • **max-content**: The intrinsic preferred height or width
  • **min-content**: The intrinsic minimum height or width (for example, a block with a single letter in it has the intrinsic minimum height or width of that letter)

To quote from the W3C working group on what intrinsic sizing means:

The min-content size of a box in each axis is the size it would have if it was a float given an auto size in that axis (and no minimum or maximum size in that axis) and if its containing block was zero-sized in that axis. (In other words, the minimum size it has when sized as “shrink-to-fit”.)

The max-content size of a box in each axis is the size it would have if it was a float given an auto size in that axis (and no minimum or maximum size in that axis), and if its containing block was infinitely sized in that axis. (In other words, the maximum size it has when sized as “shrink-to-fit”.)

You might assume that these keywords would be usable in a min/max function, especially when you see that such functions as fit-content use them in their definitions to describe how the function is implemented. But currently, there is no specification on how this should be achieved.

I asked the CSS working group for clarification on whether they could be used, but it seems the answer is “not right now.” They would, however, like them to be usable at some point.

A little bit about clamp()

In this next section, we will get into using the clamp() function, although still with some usage of min() and max() where applicable. As such, we should probably expand on clamp(), and the complexities our three functions can create when used together, before proceeding.

Firstly, remember that clamp() takes exactly three properties: a minimal value, a preferred or default value, and the maximum value. So, clamp(MIN, DEFAULT, MAX).

The ease of reasoning about clamp() is a great benefit. With clamp(), you’ll be able to alleviate some of the QA and designer madness that you as a developer may have noticed at times. I mean, of course, the madness of pixel-perfect design.

#css #web-development #programming #developer

A Guide to the min(), max(), and clamp() CSS Functions
2.40 GEEK