grid-auto-columns

Avatar of Mojtaba Seyedi
Mojtaba Seyedi on

DigitalOcean joining forces with CSS-Tricks! Special welcome offer: get $100 of free credit.

The grid-auto-columns CSS property is part of the CSS Grid Layout specification, specifying the size of the grid columns that were created without having an explicit size. In other words, this property sets the size of implicit columns and any other columns that have not been explicitly sized in the grid-template-columns property.

.grid-container {
  display: grid;
  grid-template-areas: "media detail detail";
  grid-template-columns: 200px 400px;
  grid-auto-columns: 150px;
}

That example creates a grid container with three columns defined by grid-template-areas. The first two columns have an explicit size set by grid-template-columns, but not the last column. This is where grid-auto-columns kicks in and sets that column’s size to 150px.

grid-auto-columns use cases

As said above, grid-auto-columns sets the size of any columns that don’t have an explicit size. Now the question is, what kind of columns don’t have an explicit size? Or, how does a grid create columns without an explicit size?

Here are some situations where that might come up.

Columns that are defined by grid-template-areas that have no explicit size set by grid-template-columns

The first case is the one that we saw at the top of this article. A grid can have an explicit column defined by grid-template-areas without having its size set explicitly by the grid-template-columns property.

.grid-container {
  display: grid;
  grid-template-areas: "media detail detail"; /* 3 columns */
  grid-template-columns: 200px 150px; /* 2 sizes */
}

The first column is set to 200px and the second one has its size set to 150px. And since the last column is not set to any explicit size, it will be set to auto and take up the available space that’s leftover from the other two columns.

Three column tracks that two of them have an explicit size but not the last one is set to auto.

If we add the grid-auto-columns to the above example we can control the size of the last column too:

.grid-container {
  display: grid;
  grid-template-areas: "media detail detail";
  grid-template-columns: 200px 150px;
  grid-auto-columns: 150px;
}

Now as you can see in the following image, the last column’s size is set to 150px:

Three column tracks with the last column’s size is set to 150px using grid-auto-columns property.

Note that the tracks that don’t have an explicit size are auto-sized.

Implicit columns are created when there are more grid items than cells

A grid that is defined by the grid-template-columns, grid-template-rows or/and grid-template-areas is called an explicit grid, meaning that all the grid tracks have a set size. Let’s say, for example, we have 12 HTML child elements in a parent grid container, and we explicitly define three columns and four rows in the grid.

.grid {
  display: grid;
  grid-template-rows: repeat(4, auto);
  grid-template-columns: repeat(3, auto);
}

We have implicit grid tracks for those columns and rows because there’s no sizing information. Only the number of columns and the number of rows.

One situation where you’ll find implicit columns is when there are more grid items than there are defined columns. Imagine in our last example that we now have more than 12 HTML elements. We previously set up three columns and four rows, so there are exactly 12 cells in the grid — the perfect amount for our 12 elements. But with more than 12 elements, we suddenly have an overflow problem, right?

Not at all! CSS Grid’s auto-placement algorithm creates additional rows or columns to hold the extra items. Those extra columns and rows are called implicit tracks.

By default, the auto-placement algorithm creates row tracks to hold extra items. In the following example, we ask our grid to lay out the extra items in columns (not rows), so we need to set the auto-placement algorithm to column. Awesome, now our grid is capable of holding everything, no matter how many items we toss at it.

However, the implicit columns are sized automatically based on the space that’s left. That’s why grid-auto-columns is so useful —we can give all of those columns a size and CSS Grid will stop filling columns when it reaches the last element, even if the last column in the last row of the grid falls short of the grid’s full width,

Say we size those implicit grid columns to 250px:

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 150px);
  grid-auto-flow: column; /* Set the auto-placement algorithm to column */
  grid-auto-columns: 250px;
}

Now, no matter how many implicit columns get created, they will all have their size set to 250px.

Single row grid with five columns with grid-auto-columns setting implicit columns.
The explicit grid is marked with a solid line and the implicit one is marked using a dotted line.

Implicit columns are created when we position an item outside of the explicit grid

Another scenario where the grid-auto-columns property comes in handy is when implicit tracks are created when we position an item outside of the explicit grid. The implicit tracks are automatically created to make a place for that item.

.grid-container {
  display: grid;
  grid-template-columns: 150px 150px 150px; /* 3 explicit columns */
  grid-auto-columns: 150px; /* Size of the implicit columns */
}

.grid-item:last-child {
  grid-column: 5; /* Placed in 5th column in a 3-column grid */
  grid-row: 3;
}

So what we did there was set the last .grid-item child in the fifth column… but there is no fifth column in our three-column grid! That puts the last grid item outside the explicit grid, which creates two implicit column tracks. Even though those columns were created for us, we can set them to 150px using the grid-auto-columns property.

Five by three grid where the cell in the last row and last column contains the last grid item.
Positioning the last child into the fifth column of a three-column explicit grid causes two implicit column tracks. We set those columns size to 150px using the grid-auto-columns property.

Syntax

grid-auto-columns: <track-size>+
Full Definition
where
<track-size> = <track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( [ <length> | <percentage> ] )

where
<track-breadth> = <length-percentage> | <flex> | min-content | max-content | auto <inflexible-breadth> = <length> | <percentage> | min-content | max-content | auto

where
<length-percentage> = <length> | <percentage>
  • Initial value: auto
  • Applies to: grid containers
  • Inherited: no
  • Computed value: as specified, but with relative lengths converted into absolute lengths
  • Percentages: refer to corresponding dimension of the content area
  • Animation type: if the list lengths match, by computed value type per item in the computed track list; discrete otherwise

Multiple track sizes

We can specify multiple column sizes for grid tracks using the grid-auto-columns property. In this case, the multiple track size works as a pattern and it gets repeated if necessary.

.grid-container {
  display: grid;
  grid-template-columns: 150px 150px;
  grid-auto-columns: 50px 100px 200px;
}

.grid-item:last-child {
  grid-column: 8;
}

Here, we move the last child of our grid out of the explicit columns and our grid creates implicit columns to hold that item as a result. This grid has two explicit columns (150px 150px) and since the last item wants to be in the eighth column (grid-column: 8), six implicit columns are automatically generated in the grid.

The grid-auto-columns sets the first implicit column size to 50px, the second to 100px and third column to 200px. Since we have more than three implicit columns, our grid repeats this pattern to size them.

A grid with a multiple column sizes set by the grid-auto-columns property. The multiple values get repeated as the size of the implicit columns.

If we had one more implicit columns, what would be the size of that column?

Show me the answer!

It would be 150px, but I bet you knew that without looking. 😀

Values

The grid-auto-columns values are almost the same as the values of the grid-template-columns property, except in grid-auto-columns you can’t use the following values:

  • none
  • [linename]
  • repeat()
  • subgrid
  • masonry
/* Keyword values */
grid-auto-columns: auto;
grid-auto-columns: min-content;
grid-auto-columns: max-content;

/* single track-size values */
grid-auto-columns: 200px;
grid-auto-columns: 30vmin;
grid-auto-columns: 50%;
grid-auto-columns: 1.5fr;
grid-auto-columns: minmax(100px, 2fr);
grid-auto-columns: minmax(min-content, 1fr);
grid-auto-columns: fit-content(15rem);

/* multiple track-size values */
grid-auto-columns: 100px 1fr;
grid-auto-columns: 200px min-content 1fr;
grid-auto-columns: 100px 200px 50px 10%;
grid-auto-columns: minmax(100px, auto) auto max-content fit-content(200px);

/* Global values */
grid-auto-columns: inherit;
grid-auto-columns: initial; /* same as `auto` */
grid-auto-columns: revert;
grid-auto-columns: revert-layer;
grid-auto-columns: unset;

<length>

This value can be any valid and non-negative CSS length, such as px, em and rem , among others to specify the track size (i.e. width) of the column.

<percentage>

This is a non-negative value relative to the inner inline size of the grid container. If the size of the grid container depends on the size of its tracks, then the percentage must be treated the same as declaring auto.

One disadvantage of using a percentage value is that, if you add gaps between the tracks, the size of the gaps will be added to the size of the tracks which may cause an overflow. Use the fr unit or auto keyword to size the tracks and prevent that from happening.

<flex>

This is a non-negative value expressed in fr units and it allows you to create flexible grid tracks by specifying the size of a track as a fraction of the available space in the grid container. That way, as the grid changes widths, so do the columns, making for a more responsive grid.

For example, consider a grid container that’s 900px wide and it has three implicit columns. Let’s say the width of the first (left) implicit column is fixed (i.e. it doesn’t change) at 300px while the second column takes up one fractional unit (1fr) and the third column weighs in at two fractional units (2fr):

.grid-container {
  display: grid;
  width: 900px;
  grid-auto-columns: 300px 1fr 2fr;
}

The second two columns are fractional, so they’re going to take any remaining available space. And, in this case, the available space is whatever is leftover after the first column’s fixed 300px width is taken into account. After that, the second two columns divvy up what’s left according to how many fractions they get.

In this example, the remaining and available space is 600px (i.e. 900px minus 300px). The second columns gets one fraction (1fr) of that space and the third column gets two fractions (2fr). Let’s get math-y for a moment to figure out the width of one fraction of 600px:

1fr = ([Grid Container Width] - [Fixed Column Width]) / [Sum of the flex factors]
1fr = (900px - 300px) / 3
1fr = 600px / 3
1fr = 200px

Aha! One fraction is 200px. And since the second column is 1fr, it must be 200px as well. That leaves us with 400px of available space (i.e. 900px300px200px) which just so happens to be twice the size of the second column. And twice the size of the second column is 2fr (1fr(2))!

minmax(min, max)

The minmax() function accepts two arguments: a minimum length value and a maximum length value. And what that tells a grid container is that the grid-auto-columns can be no narrower than the minimum value, but no wider than the maximum value. Our Guide to CSS Functions has a more thorough, detailed explanation of how the function works.

Take the following example:

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

There’s two columns here: one that’s 200px wide, and another that’s expressed as minmax(100px, 400px). Looks weird, right? But all that’s saying is that the second column must take up at least 100px of space, but no more than two fractions of whatever the available space is after the first columns 200px is taken into account.

In clearer terms: As long as there’s more than 100px of available space, then the second column can flex up to 400px but has to stop there. Otherwise, the column is 100px wide.

The min and max arguments accept all the following values, except that the min value can’t be a flex value (e.g. 1fr):

<length-percentage> | <flex> | min-content | max-content | auto

So, this is invalid since the min value is a flex value:

grid-auto-columns: minmax(1fr, 500px) 3fr;

But these are totally valid:

grid-auto-columns: minmax(auto, 1fr) 3fr;
grid-auto-columns: minmax(200%, 1fr) 1fr;

auto

The auto keyword behaves similarly to minmax(min-content, max-content) in most cases.

Since auto track sizes can be stretched by the align-content and justify-content properties they will take up any remaining space in the grid container by default (you know, auto-matically). That said, auto track sizes can’t win a fight against fr units when allocating the remaining space — they adjust to the maximum size of their content.

Take a look at the result of these two track examples:

grid-auto-columns: auto auto auto;
grid-auto-columns: auto 1fr auto;

When all three columns are set to auto (which we also could have written as repeat(3, auto) — but more on that later), all they do is share equal space. But when we drop a fractional unit in the middle as the second column, the auto columns are only as wide as the content inside them and the 1fr column takes up the remaining space.

Demonstrating the behavior of fr unit next to auto tracks

min-content

The min-content keyword represents the smallest amount of space possible that an element can take in a grid container without overflowing its content. The content can be texts, images or videos.

Let’s say the content is “CSS is awesome.” the min-content is the width of the world “awesome” because that is the widest part of the content (wider than “CSS” and “is” combined). If the column goes any narrower, then the text starts to overflow the container.

In code, that looks like this:

.grid {
  display: grid;
  grid-auto-columns: min-content 1fr;
  gap: 1rem;
}

…which results in something like this:

Demonstrating the behavior of the min-content keyword in a grid layout

max-content

The max-content keyword represents the smallest size required for an element to fit all of its content without being wrapped or overflowed. I know, a name that includes “max”makes it sound like we’re dealing with a maximum size, so this value can be a bit of a brain teaser.

If we revisit our min-content example above, a grid track with a size value of max-content will grow until its content can fit into a single line. So, in the case of “CSS is awesome” the max-content is however much space those three words take up together on one line.

.grid {
  display: grid;
  grid-auto-columns: max-content 1fr;
  gap: 1rem;
}
Demonstrating the behavior of the max-content keyword in a grid layout

fit-content(<length-percentage>)

The fit-content() function (there’s a solid explanation of it in our Guide to CSS Functions) uses the space available and accepts a percentage or length value as the maximum size allowed for a grid track while ensuring the track never goes beyond the max-content and never shrinks beyond a minimum. The minimum is often, but not always, equal to the min-content.

.grid {
  display: grid;
  grid-auto-columns: fit-content(700px) fit-content(700px) 1fr;
  gap: 1rem;
}

In the figure below, the first column doesn’t expand beyond its max-content size (i.e. the width of the words “fit-content(700px)” on a single line) — it only stretches out to fit its content. The second column, however, has way more content in it, and stops stretching once it gets to a width of 700px, which is the limit set to the function:

Showing fit-content behavior in a CSS grid.
So, what we’re saying here for the first two columns is that they should be as wide as their maximum content, but only up to 700px. If it can fit all the content within that limit, great, stop where the max-content is. Otherwise, show as much you can up to 700px, then start breaking into additional lines.

Examples

Let’s create a gallery that has three images in three columns, and in case more images get added, we want them to cascade to a new row and column. To do that we need to create three explicit columns and place the extra items outside those three columns, since this can cause implicit columns and hypothetically, we don’t know how many columns are going to get generated, we can control the size of those implicit columns using grid-auto-columns property.

.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(200px, 1fr));
  grid-auto-columns: minmax(100px, 200px);
  gap: 1rem;
}
A gallery created by CSS Grid that has three explicit columns and three implicit ones.
We set the size of the implicit columns to minmax(100px, 200px) using grid-auto-columns.

Specifications

CSS Grid Layout Module 1 (Candidate Recommendation)

Browser support

More information