
Dynamic Sizing with CSS max()

It wasn't that long ago that CSS functions like max() (or min(), or clamp()) were entirely unthinkable: these open up access to dynamic values and functionality that could only be achieved historically through the use of JavaScript. Now, they play a really important role in our ability to develop fluid, responsive layouts, elegantly adapting across different devices.
Unpacking max()
Much like it's sibling min(), max() is very straightforward at it's core; it accepts and evaluates a set of values, and returns the largest. This allows us as developers and designers to expand elements to fill available space, whilst also maintaining a limit for usability and aesthetics.
Here's a simple example to get us started:
.container { height: max(50vh, 30rem);}Here, we define the height of an element: .container. Using max(), the overall height of .container will be set to either 50% of the viewport height (50vh) or 30rem, whichever of the two is the greater. I should mention here that there's no limit to the number of different values you can place within max(), this could easily be a combination of viewport, percentage, fixed, and fluid units all together in a single statement. The browser would still select whichever of the values is largest at that time.
Practical Applications
Responsive or Adaptive Typography
In a very similar vein to that which I described for min(), one of the most interesting and powerful uses for max() is in adaptive (or responsive) typography.
Here's a quick example where the font size of an h1 heading will increase as the viewport does but will never be smaller than 2rem:
h1 { font-size: max(2rem, 5vw);}Using max() in this way means that we can ensure that our text remains legible across screen sizes without becoming disproportionately small (or large).
Responsive Spacing and Layouts
Beyond typography, max() is of course invaluable when it comes to implementing responsive layouts and spacing when elements need to expand based on content or viewport size, but still have a logical maximum.
Here's another example:
.section { padding: max(1rem, 3vw);}As is often the case in my articles, this is a simple (but hopefully illustrative) example; the padding around .section will grow as the viewport does ‑ potentially offering more breathing room around the responsive heading we described above. However, it will also be restricted (or capped) at 1rem, preventing overly spacious of awkward layouts on larger screens.
Browser Support and Considerations
As will all sound very familiar if you've read this same section on my article about min(), browser support for max() is very good, mirroring min() exactly. However, if you still need to support more legacy browser such as Internet Explorer, then you're going to have to give a little more thought to how you structure your code.
There are two general strategies that you could consider:
Media Queries
I would argue that the power of these types of dynamic value functions comes from the fact that they do away with the need for lots of media queries. Nevertheless, in browser environments where max() isn't available, media queries will achieve similar results.
Revisiting our example from up towards the top of the article, you could achieve the same with a little more code like this (and have it work on Internet Explorer):
.container { height: 30rem;}@media (min-height: 30rem) { .container { height: 50vh; }}The min‑* and max‑* properties
However, if we're only looking for a max between two values (rather than a wider array) and using certain dimensional properties (width, height, etc), then the same can be achieved using a combination of dimension properties (in this case: height), and the min‑* or max‑* properties. Like this:
.container { height: 50vh; min-height: 30rem;}This achieves sort of the same thing in that .container will have a height of 50vh, but will also always be a minimum of 30rem high.
Admittedly, the comparison between two values like this is a fairly rudimentary use for max() anyway, so this solution isn't going to cover more in‑depth use cases. However, there is an argument that if what you need to achieve is this simple anyway, there's really no need to use max() (or min()) at all...
Related Articles

Object Equality in JavaScript: {} isn't Equal to {}. Object Equality in JavaScript:

React Portals Explained. React Portals Explained

Access Search Parameters in Next.js SSR'd Layout. Access Search Parameters in Next.js SSR'd Layout

Primitive vs. Reference Types in JavaScript. Primitive vs. Reference Types in JavaScript

Check If Three Values are Equal in JavaScript. Check If Three Values are Equal in JavaScript

Extends and super in JavaScript Classes. extendsandsuperin JavaScript Classes
Template Literals in JavaScript: Writing Multi‑Line Strings. Template Literals in JavaScript: Writing Multi‑Line Strings

How to Find the Best Web Developer Near You: A Guide for Local Businesses. How to Find the Best Web Developer Near You: A Guide for Local Businesses

Understanding Signals in Angular: The Future of Reactivity. Understanding Signals in Angular: The Future of Reactivity

The Role of Dependency Injection in Angular. The Role of Dependency Injection in Angular

String.startsWith(), endsWith(), and includes() in JavaScript. String.startsWith(),endsWith(), andincludes()in JavaScript
Event Delegation in JavaScript. Event Delegation in JavaScript