minmax()

Image
Saleh Mubashar on

Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.

The CSS minmax() function is used exclusively with CSS Grid to define a size range for grid tracks (i.e., the grid’s rows and columns). It lets you specify two arguments — a minimum size and a maximum size for a track — allowing the grid track to grow and shrink within that range, depending on the available space.

This is not to be confused with min() and max(), which are mathematical comparison functions used across many properties to calculate a single value from a list of options. In contrast, minmax() provides a range for flexible layout in a grid, where you get to decide the lower and upper limits.

Syntax

minmax( <min> , <max> )

In short, the minmax() function accepts two arguments, one for setting the minimum size of a CSS Grid container’s track and one for setting its maximum size.

Arguments

These are the two arguments:

  • min: the minimum size of the track
  • max: the maximum size the track is allowed to grow to

Both min and max can be:

  • a <length> (e.g., 200px),
  • a <percentage> (relative to the grid container), or
  • a keyword (min-content, max-content, or auto).

Here are a few examples of valid minmax() values:

/* Lengths and Percentages */
minmax(30%, 300px)
minmax(400px, 50%)

/* Flex value only on max */
minmax(200px, 1fr)

/* Keywords */
minmax(50%, min-content)
minmax(300px, max-content)
minmax(auto, 300px)

A couple of gotchas

There are a couple of instances where the minmax() function simply won’t work.

One is that you can’t use fractional (fr) units to set a grid track’s maximum argument even though it is a valid <length> value. It might seem counterintuitive at first, but not makes sense once you remember that fractional units allow you to “take up to” a certain amount of space. So, if you try setting the max arguments with a fractional value, it invalidates the entire function.

The other instance is when the min argument is greater than the max argument, like this:

minmax(200px, 10px);

This is basically telling CSS that the track should be at least 200px and, at most, 10px. That’s backwards reasoning and invalidates the function, which simply means its ignored.

Supported properties

It’s really important to note that the minmax() function is designed to work with very specific CSS properties that are used to build layouts with CSS Grid:

Basic example

We start by setting up the element as a CSS Grid container:

.grid {
  display: grid;
}

Next, we set the sizing for the grid’s tracks:

.grid {
  display: grid;
  grid-template-columns: minmax(100px, 400px) 1fr 1fr;
}

This creates a grid layout with three columns:

  • The first column is sized with minmax(100px, 400px). That means the track size will never shrink below 100px. And, if space allows, it can grow up to 400px.
  • The other two columns are sized with 1fr. That means they equally share the first column’s leftover space.
A three-column grid layout. The first item takes half the space with the second and third items splitting the rest of the available space.

Rachel Andrew has a great video explainer on minmax() and responsive grids that walks through common patterns and gotchas.

Using repeat(), auto-fit, and auto-fill

While the example above works, it’s not very responsive. On very narrow screens, forcing the first column to stay at least 100px can cause horizontal scrolling. On the other hand, giving it a maximum of 400px prevents it from growing too large on wide screens, resulting in unused space.

To fix this, we need a way for the browser to automatically adjust the number of columns and the column widths for all viewports without having to write media queries.

First off, the repeat() function saves us from writing the same column definition multiple times. Instead of this:

grid-template-columns: minmax(250px, 1fr) minmax(250px, 1fr) minmax(250px, 1fr);

…we can write this:

grid-template-columns: repeat(3, minmax(250px, 1fr));

This is cleaner, but still locks the grid to three columns, which means overflow on smaller screens. To fix this, we can combine repeat() with the auto-fill and auto-fit keywords.

Sara Soueidan has a great explanation of how the auto-fit and auto-fill keywords work. In short, they tell the browser to create as many columns as it can fit into the available space and then wrap any leftover items into new rows, as needed.

So, what exactly is the difference between those keywords?

  • auto-fill: Fills the row with as many columns/rows as possible, even if some are empty; they still take up space.
  • auto-fit: Does the same, but collapses any empty columns/rows and redistributes that space to existing columns/rows.

Let’s look specifically at the auto-fit keyword, as it is ideal for our example. We want the grid container’s columns to stretch when there’s room available:

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

Notice how the grid automatically packs in as many items into one column, then decides to wrap into multiple rows as it starts running out of space. And notice how the items are always equally sized, but never fall below 250px in width.

Note: Using auto-fit with components like images or fixed-aspect cards can lead to distortion when only one or two items remain, since they stretch to fill the row width. To prevent this, consider applying a max-width to the items or using auto-fill instead.

For example, in the layout below, if you resize the window, you’ll notice that when only one or two items fit per row, they stretch to fill the available space, distorting the intended design.

Preventing grid overflow with min()

Although our last example is more responsive than the first example we looked at, theres still an edge case to consider. If the container becomes narrower than the min argument (which is set to 250px), then the grid items won’t shrink any further and they overflow the container.

Grid overflow when the viewport width is less than 250px

To solve this, we can wrap the minimum size in a min() function that is nested inside the minimax() function, like so:

grid-<span class="hljs-keyword">template</span>-columns: repeat(<span class="hljs-keyword">auto</span>-fit, minmax(<span class="hljs-built_in">min</span>(<span class="hljs-number">250</span>px, <span class="hljs-number">100</span>%), <span class="hljs-number">1</span>fr));

What this is telling the browser is to make each column up to 250px, unless 100% of the container equals something smaller — then go with that instead. In other words:

  • Is 100% less than 250px? If yes, then don’t go below that.
  • Is 100% greater than 250px? If yes, then take up the full space.

The max-content and min-content keywords

At this point, it’s worth discussing what the max-content and min-content keywords are and how they affect the minmax() function. Both relate to an element’s intrinsic content size, which is the size the content wants to take up before layout constraints are applied.

The max-content keyword is used to represent the content’s maximum possible intrinsic size. For example, if a paragraph fits on a single line, the max-content keyword will stretch the column wide enough to show that line in full, even if it’s really long. When used in minmax(), this allows a grid column to grow just enough to avoid breaking the content.

The min-content keyword does the opposite. It sets the column to be as narrow as possible without cutting off the content. For text, that means it will wrap the content as much as it can. The longest unbreakable word is what determines the minimum width the column will take.

You can see the difference between in the following example:

Notice how max-content causes a grid overflow. This is because max-content essentially tells the browser to “make this column wide enough to show all the content without any line breaks.” **If the content is too long, the column stretches beyond the container, leading to overflow.

Be careful when using min-content or max-content. They can be unpredictable and result in very narrow or very wide columns, depending on the content.

Browser support

Specification

The CSS minmax() function is defined in the CSS Grid Layout Module 2 specification, which is in Candidate Recommendation Draft status at the time of writing.