Happy holiday folks! All the best from us at Digitpaint

Day 7

Maximum grid control with auto-fill and minmax()

Wouldn't it be great if you could create a fully flexible grid, that is flexible both in size and number of tracks? Say hello to grid's auto-fill and minmax()!

In the demo below some grids with different column definitions are shown. Toggle the button to change the width of the grid container (only works on tablets and desktops), manually change the width of your browser window, add or remove some presents, and see what happens to the grids.

Fixed width vs flexible width columns

Auto-fill/minmax() vs auto-fit/minmax() columns

So what do we see here?

In a grid without autofill, you define the number of column tracks beforehand. This way, the grid will always have that exact number of columns. Depending on the way in which the width of these tracks have been defined, the columns will either have a fixed width, or a flexible width. This is what you see in action in the first example.

// Grid with fixed width column tracks
.grid--fixed {
  grid-template-columns: repeat(5, 135px);

// Grid with flexible width column tracks
.grid--flexible {
  grid-template-columns: repeat(5, 1fr);

In these examples, tracks on one row will never wrap to the next. When the container is too small for the column tracks to fit in them, they will simply overflow. This is what happens in the first example after you press the resize button. In the second example, the items will never exit their container; they will always take up a fraction of the available space of the container.

If we would want to have a different number of column tracks for other screen sizes, we would have to use media queries to do so. But by using auto-fill or auto-fit, the tracks wrap to the next line if they wouldn't fit next to eachother.


With the auto-fill keyword used instead of the number that represents the amout of repetitions, a grid is created that has as many tracks as could possibly fit into the container, taking the track size and the grid-gap into account.

.grid--fill {
  grid-template-columns: repeat(auto-fill, 135px);
  grid-gap: 20px;

As you can see in the grid outline in the image below, it also creates empty grid tracks when there's room left in the container.

Tracks in a grid with auto-fill: empty tracks will remain part of the grid

When there are more tracks than would fit inside the container, the tracks will automatically go to the next line. If even a single track is bigger than the container, only 1 track is placed per line.


The auto-fit keyword behaves the same as auto-fill, except for the empty tracks. Having leftover space does not result in empty tracks. These are instead collapsed (see the 4th example above and the grid outline in the image below).

.grid--fit {
  grid-template-columns: repeat(auto-fit, 135px);
Tracks in a grid with auto-fit: empty tracks are collapsed


We can start creating real flexible grids if we use auto-fill and auto-fit in combination with the minmax() function. Minmax() defines a minimum and a maximum size for the column tracks. If we use a value between 0 and 1, representing the percentage divided by 100, as the maximum value, the grid will become truly flexible.

.grid--fill-flexible {
  grid-template-columns: repeat(auto-fill, minmax(135px, 1fr));

In the example code above, the tracks have a minimum size of 135px, and a maximum size of 1 fr. When the 135px tracks and the git-gaps are assigned, the remaining space will be equally distributed between the tracks.

In the case of auto-fill, some space is reserved for empty tracks that fit in the container (5th example above). This results in the items suddenly becoming wider when you reduce the width of your browser window to below 1130px. This happens because the empty 6th track would no longer fit at that point, and the available space is distributed between the 5 remaining tracks.

Auto-fit only looks at the actual elements, and stretches those across (see 6th example above). See how the presents are distributed when you remove one of the presents by clicking on it.

Compatible with

Support for the features demonstrated above is pretty good right now.

  • edge
  • FireFox
  • Chrome
  • safari
  • opera
  • ios safari 10.3+
  • Chrome for Android

Learn more

Demo source code

Do you want to dig in the nitty-gritty of this demo, check out the source files:

Back to home