Flexible Sized Grids with auto-fill and minmax

Various unimplemented parts of the CSS Grid Layout specification are making their way into browsers, and I was excited to see that the auto-fill keyword and minmax() function are appearing. At the time of writing these examples work best in Firefox Nightly or Developer Edition.

auto-fill and auto-fit

When creating a grid on an element we can use the repeat() keyword to repeat all or part of our track definition. The following definition would create a grid with 10, 100 pixel width column tracks.

.wrapper {
 grid-template-columns: repeat(10, 100px);
}

We could create 10 flexibly sized equal width tracks by using the fr unit.

.wrapper {
 grid-template-columns: repeat(10, 1fr);
}

What this wouldn’t let us do however is to ask grid to create as many tracks of a certain size as would fit into the viewport, or other containing element. We will always have a grid of ten column tracks – fixed width in the first example or flexible in example 2. What would be nice would be to get a grid of as many tracks as possible of a certain size as could fit into the container. This is what auto-fill and auto-fit do.

To create a grid with as many 100 pixel tracks as will fit in the container we can use the auto-fill keyword rather than a number.

.wrapper {
 grid-template-columns: repeat(auto-fill, 100px);
}

According to the spec this will create a grid with as many tracks as will fit into the container, and will taking any grid-gap value into account,

“ the number of repetitions is the largest possible positive integer that does not cause the grid to overflow its grid container (treating each track as its max track sizing function if that is definite or as its minimum track sizing function otherwise, and taking grid-gap into account)”

You can then use grid auto-placement to place items on this grid. Or position items if you had some idea of available tracks. If you use the auto-fill keyword empty tracks will remain as part of the grid. If you were to use the alternate auto-fit keyword, this would behave in the same way as described above but once all grid items have been placed any completely empty tracks will be dropped.

minmax()

To achieve a truly flexible grid – flexible both in size of tracks and number – we need an additional piece of the puzzle – minmax(). We can give this function a minimum and maximum size that we want our track to be. So the following would make tracks a minimum of 100 pixels and a maximum of 200 pixels.

.wrapper {
 grid-template-columns: repeat(auto-fill, minmax(100px, 200px));
}

Still not fully flexible though. So instead we could use the fraction unit as our maximum value. This would result in tracks of a minimum of 100 pixels and a maximum of 1 fraction unit of the available space. After as many 100 pixel tracks are assigned, we then have the remaining space to distribute. Our tracks are allowed to be greater than 100 pixels wide so the remaining space is equally distributed. The result as many equal width, flexible sized columns as can fit inside the container.

.wrapper {
 grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

You can see an example of this behaviour – assuming you have Firefox Nightly or another browser supporting this very new feature – in the CodePen below.

Leave a Reply