CSS Grid generator
Choose the number of columns and rows, their sizes and the gaps — the grid updates in the preview at once and the ready-made grid CSS appears below.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 12px;
}
How to use it
- In the Columns and Rows blocks set how many you need (up to 6 columns and 4 rows), then pick a size for each track:
1fr,2fr,auto,100px,200pxorminmax(100px, 1fr). - Adjust
column-gapandrow-gapfor the space between cells, andjustify-itemsandalign-itemsfor how content sits inside each cell. - Click a numbered cell in the preview (or select it with
TabandEnter) and stretch it across several columns or rows withgrid-column: spanandgrid-row: span. - Need a responsive grid? Tick the “Responsive” box: columns are built with
repeat(auto-fill, minmax(…px, 1fr))and adapt to the width on their own. Press “Copy” to take the code.
How it works
grid-template-columns and grid-template-rows
An element with display: grid becomes a grid. grid-template-columns sets the width of the columns and grid-template-rows the height of the rows; each value is one track, the strip between two grid lines. Tracks can be sized in pixels, percentages, auto or the fr unit. The generator folds equal tracks into repeat() for you.
.grid {
display: grid;
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr;
}
The fr unit and repeat()
1fr is one share of the free space in the container. With 1fr 2fr the second column is twice as wide as the first: fixed sizes (200px) and gaps are subtracted first, and what is left is divided by the fr shares. repeat(3, 1fr) is a short way to write three equal columns, and minmax(100px, 1fr) sets a minimum: the column is never narrower than 100px but grows when there is room.
.grid {
grid-template-columns: repeat(3, 1fr);
}
gap, justify-items and align-items
gap (that is row-gap and column-gap) separates the tracks and adds no space around the outside of the grid. justify-items aligns the content of a cell horizontally and align-items vertically. The default is stretch, so an item fills its whole cell; start, end and center shrink the item to the size of its content.
.grid {
gap: 12px 24px; /* row-gap column-gap */
justify-items: center;
align-items: start;
}
Spanning columns and rows
grid-column: span 2 tells an item to take two columns and grid-row: span 2 two rows. With automatic placement the other items move on to the next free cells. If the stretched items leave you short of the rows you declared, the browser creates extra implicit rows; their height is controlled by grid-auto-rows.
.item:nth-child(1) {
grid-column: span 2;
grid-row: span 2;
}
A responsive grid without media queries
repeat(auto-fill, minmax(140px, 1fr)) chooses the number of columns by itself from the container width: each column is at least 140px and the leftover space is shared between them. Cards wrap on narrow screens and you do not need to write an @media rule. auto-fill keeps empty tracks, while auto-fit collapses them and stretches the existing items.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 12px;
}
FAQ
What is the fr unit?
fr (fraction) is a share of the free space in the container. After fixed sizes and gap are subtracted, the rest is divided in proportion to the fr values: with 1fr 2fr the second column is twice as wide as the first.
What is the difference between auto-fill and auto-fit?
When there are fewer items than fit in a row, auto-fill keeps the empty tracks, so the items do not stretch. auto-fit collapses the empty tracks to zero and the existing items stretch into the free space. When the row is completely full there is no difference.
When should I use Grid and when Flexbox?
Flexbox is one-dimensional: it is great for lining items up in a single row or column. Grid is two-dimensional: it suits cases where you control rows and columns together, such as a page layout or a grid of cards. They do not exclude each other and are often used together.
Why did an extra row appear in my grid?
If items do not fit into the rows set in grid-template-rows (for example, one item covers several cells), the browser adds implicit rows. You can set their height with grid-auto-rows.