How to Use minmax() CSS Grid

The CSS Grid Layout Module takes responsive design to the next level by introducing a new kind of flexibility that was never seen before. Now, we can’t only define custom grids blazingly fast solely with pure CSS, but the CSS Grid also has many hidden gems that allow us to further tweak the grid and achieve complicated layouts.

The minmax() function is one of these less widely known features. It makes it possible to define the size of a grid track as a minimum to maximum range so that the grid can adapt to the viewport of each user the best possible way.

Syntax

The syntax of the minmax() function is relatively simple, it takes two arguments: a minimum and a maximum value:

minmax(min, max)

The min value has to be smaller than the max, otherwise max gets ignored by the browser.

We can use the minmax() function as the value of the grid-template-columns or grid-template-rows property (or both). In our example, we’ll use the former, as it’s a much more frequent use case.

.container {
  display: grid;
  grid-template-columns: minmax(100px, 200px) 1fr 1fr;
  grid-template-rows: 100px 100px 100px;
  grid-gap: 10px;
}

In the Codepen demo below, you can find the HTML and CSS code we’ll use throughout the article.

We can use different kind of values inside the minmax() function, all depends on what kind of custom grid we want to create.

Static length values

There are two basic ways how we can use the minmax() function with static length values.

Firstly, we can use minmax() only for one grid column and define the width of the other columns as simple static values (pixels here).

grid-template-columns: minmax(100px, 200px) 200px 200px;

On the gif demo below, you can see that this layout is not responsive, however the first column has some flexibility. The second and the third columns retain their fixed width (200px) while the first column ranges from 100px to 200px, based on the available space.

Fixed minmax() with fixed columns

Secondly, we can define the width of more than one grid column using minmax(). The min and max values are both static, so by default, the grid is not responsive. However, the columns themselves are flexible, but only between 100px and 200px. They grow and shrink simultaneously as we change the viewport size.

grid-template-columns: minmax(100px, 200px) minmax(100px, 200px)
                       minmax(100px, 200px);
Fixed minmax() in all columns

Note that we can also use the repeat() function togehter with minmax(). So, the previous code snippet can also be written like this:

grid-template-columns: repeat(3, minmax(100px, 200px));

Dynamic length values

Apart from static values, the minmax() function also accepts percentage units and the new fraction (fr) unit as arguments. By using them, we can achieve custom grids that are both responsive and change their dimensions according to the available space.

The code below results in a grid in which the width of the first column ranges between 50% and 80% while the second and the third one evenly share the remaining space.

grid-template-columns: minmax(50%, 80%) 1fr 1fr;
Minmax() with dynamic values

When we use dynamic values with the minmax() function, it’s crucial to set up a rule that makes sense. Let me show you an example where the grid falls apart:

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

This rule doesn’t make any sense, as the browser is unable to decide which value to assign to the minmax() function. The minimum value would lead to a 1fr 1fr 1fr column width, while the maximum to 2fr 1fr 1fr. But, both are possible even on a very small screen. There’s nothing the browser can relate to.

Here is the result:

Misused minmax()

Combine static and dynamic values

It’s also possible to combine static and dynamic values. For instance, in the Codepen demo above, I used the minmax(100px, 200px) 1fr 1fr; rule that results in a grid where the first column ranges between 100px and 200px and the remaining space is evenly shared between the other two.

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

It’s interesing to observe that as the viewport grows, first, the first column grows from 100px to 200px. The other two, ruled by the fr unit, begin to grow only after the first one reached its maximum width. This is logical, as the goal of the fraction unit is to divide up the available (remaining) space.

Combine static and dynamic values

The min-content, max-content, and auto keywords

There’s a third kind of value we can assign to the minmax() function. The min-content, max-content, and auto keywords relate the dimensions of a grid track to the content it contains.

max-content

The max-content keyword directs the browser that the grid column needs to be as wide as the widest element it contains.

On the demo below, I placed a 400px-wide image inside the first grid track, and used the following CSS rule (you can find a Codepen demo with the full modified code at the end of the article):

.container {
  grid-template-columns: max-content 1fr 1fr;
  /**
  * The same with the minmax() notation:
  * grid-template-columns: minmax(max-content, max-content) 1fr 1fr;
  */
}

I haven’t used minmax() notation yet, but in the code comment above you can see how the same code would look like with it (although it’s superfluous here).

Grid column with max-content

As you can see, the first grid column is as wide as its widest element (here the image). This way, users can always see the image in full size. However, under a certain viewport size, this layout is not responsive.

min-content

The min-content keyword directs the browser that the grid column needs to be as wide as the narrowest element it contains, in a way that doesn’t lead to an overflow.

Let’s see how the previous demo with the image looks like if we change the value of the first column to min-content:

.container {
  grid-template-columns: min-content 1fr 1fr;
  /**
  * The same with the minmax() notation:
  * grid-template-columns: minmax(min-content, min-content) 1fr 1fr;
  */
}

I left the green background below the image so that you can see the full size of the first grid cell.

Grid column with max-content

As you can see, the first column retains the smallest width that can be achieved without an overflow. In this example, this will be defined by the minimal width of the 4th and 7th grid cells, which stems from the padding and font-size properties, as the image in the first cell could be shrinked to zero without an overflow.

If the grid cell contained a text string, min-content would be equal to the width of the longest word, as that’s the smallest element that can’t be further shrinked without an overflow. Here’s a great article by BitsOfCode where you can see how min-content and max-content behave when the grid cell contains a text string.

Using min-content and max-content together

If we use min-content and max-content together inside the minmax() function we get a grid column that:

  1. is responsive
  2. doesn’t have any overflow
  3. doesn’t grow wider than its widest element
.container {
    grid-template-columns: minmax(min-content, max-content) 1fr 1fr;
}
Grid column with min-content and max-content

We can also use the min-content and max-content keywords together with other length values inside the minmax() function, until the rule makes sense. For instance, minmax(25%, max-content) or minmax(min-content, 300px) would be both valid rules.

auto

Finally, we can also use the auto keyword as an argument of the minmax() function.

When auto is used as a maximum, its value is identical to max-content.

When it’s used as a minimum, its value is specified by the min-width/min-height rule, which means that auto is sometimes identical to min-content, but not always.

In our previous example, min-content does equal to auto, as the minimal width of the first grid column is always smaller than its minimal height. So, the belonging CSS rule:

.container {
    grid-template-columns: minmax(min-content, max-content) 1fr 1fr;
}

could be also written like this:

.container {
    grid-template-columns: minmax(auto, auto) 1fr 1fr;
}

The auto keyword can also be used together with other static and dynamic units (pixels, fr unit, percentages, etc.) inside the minmax() function, for instance minmax(auto, 300px) would be a valid rule.

You can test how the min-content, max-content, and auto keywords work with the minmax() function in the following Codepen demo:

WebsiteFacebookTwitterInstagramPinterestLinkedInGoogle+YoutubeRedditDribbbleBehanceGithubCodePenWhatsappEmail