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.
grid-template-areas
that have no explicit size set by grid-template-columns
Columns that are defined by 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.](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1655556486212_area-1-figma587b.png)
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
:
![](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1655556500695_area-figmafece.png)
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.](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1654968264016_implicit-columns-figma1b9d.png)
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.](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1653666082291_frame2336d2.png)
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.](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1655391540303_multiple-tracks-ff-label8845.png)
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. 900px
– 300px
– 200px
) 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](png/s_3e9b3376c206e9c2ceb62fa6d09f9bb1394de2b326458ae4798cb998136cee84_1640791045930_2.auto-vs-fr5a7f.png)
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](png/s_3e9b3376c206e9c2ceb62fa6d09f9bb1394de2b326458ae4798cb998136cee84_1640791430787_3.min-contentbf25.png)
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](png/s_3e9b3376c206e9c2ceb62fa6d09f9bb1394de2b326458ae4798cb998136cee84_1640791726913_4.max-content7240.png)
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.](png/s_2910471eec3b5cc589c8c4ba691394f33bcdefb99ba14e1208cbfa068e025562_1650435904200_5.fit-content-19a07.png)
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.](png/s_beb17a5c97c57d578361ce30065f7a3ae66b9f31d714788fdbc836a2e083d94f_1655395731629_gallery.png)
minmax(100px, 200px)
using grid-auto-columns
.Specifications
CSS Grid Layout Module 1 (Candidate Recommendation)
Browser support
More information
A Complete Guide to CSS Grid
The Difference Between Explicit and Implicit Grids
Another Collection of Interesting Facts About CSS Grid
Understanding the difference between grid-template and grid-auto
IE10-Compatible Grid Auto-Placement with Flexbox
Auto-Sizing Columns in CSS Grid: `auto-fill` vs `auto-fit`
Look Ma, No Media Queries! Responsive Layouts Using CSS Grid
Related
display
.element { display: inline-block; }
gap
.element { gap: 20px 30px; }
grid-template
.element { grid-template: 100px 1fr / 300px 1fr; }
grid-template-areas
.element { grid-template-areas: "header header" "sidebar main"; }
grid-template-columns
.element { grid-template-columns: 300px 1fr; }
grid-template-rows
.element { grid-template-rows: minmax(auto, 1fr) 3fr; }