min(), max(), and clamp(): three logical CSS functions to use today

Learn how to control element sizing, maintain proper spacing, and implement fluid typography using these well-supported CSS functions.

With responsive design evolving and becoming increasingly nuanced, CSS itself is constantly evolving and providing authors increased control. The min(), max(), and clamp() functions, now supported in all modern browsers, are among the latest tools in making authoring websites and apps more dynamic and responsive.

When it comes to flexible and fluid typography, controlled element resizing, and maintaining proper spacing, min(), max(), and clamp() can help.

Background

The math functions, calc(), min(), max(), and clamp() allow mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values

CSS Values And Units Level 4

Browser support

min()

Browser Support

  • 79
  • 79
  • 75
  • 11.1

Source

max()

Browser Support

  • 79
  • 79
  • 75
  • 11.1

Source

clamp()

Browser Support

  • 79
  • 79
  • 75
  • 13.1

Source

Usage

Showing how the min() function selects a value based on a list of options and its parent. See Demo on Codepen.

You can use min(), max(), and clamp() on the right hand side of any CSS expression where it would make sense. For min() and max(), you provide an argument list of values, and the browser determines which one is either the smallest or largest, respectively. For example, in the case of: min(1rem, 50%, 10vw), the browser calculates which of these relative units is the smallest, and uses that value as the actual value.

Showing how the max() function selects a value based on a list of options and its parent. See Demo on Codepen.

The max() function selects the largest value from a list of comma-separated expressions.

Showing how the clamp() function selects a value based on a list of options and its parent. See Demo on Codepen.

To use clamp() enter three values: a minimum value, ideal value (from which to calculate), and maximum value.

Any of these functions can be used anywhere a <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> is allowed. You can use these on their own (i.e. font-size: max(0.5vw, 50%, 2rem)), in conjunction with calc() (i.e. font-size: max(calc(0.5vw - 1em), 2rem)), or composed (i.e. font-size: max(min(0.5vw, 1em), 2rem)).

To recap:

  • min(<value-list>): selects the smallest (most negative) value from a list of comma-separated expressions
  • max(<value-list>): selects the largest (most positive) value from a list of comma-separated expressions
  • clamp(<min>, <ideal>, <max>): clamps a value between an upper and lower bound, based on a set ideal value

Let's take a look at some examples.

The perfect width

According to The Elements of Typographic Style by Robert Bringhurst, "anything from 45 to 75 characters is widely regarded as a satisfactory length of line for a single-column page set in a serifed text face in a text size."

To ensure that your text blocks are not narrower than 45 characters or wider than 75 characters, use clamp() and the ch (0-width character advance) unit:

p {
  width: clamp(45ch, 50%, 75ch);
}

This allows for the browser to determine the width of the paragraph. It will set the width to 50%, unless 50% is smaller than 45ch, at which point 45ch will be selected, and visa versa for if 50% is wider than 75ch. In this demo, the card itself is getting clamped:

Using the clamp() function to limit a minimum and maximum width. See Demo on Codepen.

You could break this up with just the min() or max() function. If you want the element to always be at 50% width, and not exceed 75ch in width (i.e. on larger screens), write: width: min(75ch, 50%);. This essentially sets a "max" size by using the min() function.

Using the min() function to set a maximum width.

By the same token, you can ensure a minimum size for legible text using the max() function. This would look like: width: max(45ch, 50%);. Here, the browser selects whichever is larger, 45ch or 50%, meaning the element must be at least 45ch or larger.

Using the max() function to set a minimum width.

Padding management

Using the same concept as above, where the min() function can set a "max" value and max() sets a "min" value, you can use max() to set a minimum padding size. This example comes from CSS Tricks, where reader Caluã de Lacerda Pataca shared this idea: The idea is to enable an element to have additional padding at larger screen sizes, but maintain a minimum padding at smaller screen sizes, particularly on the inline padding. To achieve this, use calc() and subtract the minimum padding from either side: calc((100vw - var(--contentWidth)) / 2), or use max: max(2rem, 50vw - var(--contentWidth) / 2). All together it looks like:

footer {
  padding: var(--blockPadding) max(2rem, 50vw - var(--contentWidth) / 2);
}
Setting a minimum padding for a component using the max() function. See Demo on Codepen.

Fluid typography

In order to enable fluid typography, Mike Riethmeuller popularized a technique that uses the clamp() function to set a minimum font size, maximum font size, and allow for scaling from the min to the max.

Creating fluid typography with clamp(). See Demo on Codepen.

With clamp(), you can write this more clearly. Rather than requiring a complex string, the browser can do the work for you. Set the minimum acceptable font size (for example, 1.5rem for a title, maximum size (i.e. 3rem) and ideal size of 5vw.

Now, we get typography that scales with the viewport width of the page until it reaches the limiting minimum and maximum values, in a much more succinct line of code:

p {
  font-size: clamp(1.5rem, 5vw, 3rem);
}

Conclusion

The CSS math functions, min(), max(), and clamp() are very powerful, well supported, and could be just what you're looking for to help you build responsive UIs. For more resources, check out:

Cover image from @yer_a_wizard on Unsplash.