Grid Layout allows you to create responsive two-dimensional, grid-based designs. It provides a way to define rows and columns in a container and position elements within those grid cells.
Apply display: grid to an element to make it a grid container. Direct children of the grid become grid items.
grid-template-rows&grid-template-columns: Defines explicit grid tracks.- Example:
grid-template-columns: 1fr 1fr 1fr;creates three equal-width columns. grid-template: Shorthand for defining rows and columns at once.grid-teplate: 50px 50px / 50px 50px 50px;creates a 2-row by 3-column grid.
- Example:
grid-template-areas: Defines named grid areas.grid-area: Place elements in defined grid areas.gap,column-gap, &row-gap: Create spacing between grid items.
The below code creates a 3x3 grid.
“Grid lines” are used to position grid items. Grid lines are the space between columns and rows, numbered starting from 1. Grid lines are created implicitly whenever we create grid tracks.
“Grid tracks” are the space between two adjacent grid lines. Every track has a start line and an end line. The lines are numbered left-to-right, top-to-bottom.
Example: Simple 3x3 Grid
A grid “cell” is the space shared by a single row track and single column track.
.container {
display: grid;
grid-template-rows: 50px 50px 50px; /* Three 50px length rows */
grid-template-columns: 50px 50px 50px; /* Three 50px length columns */
}On the shorthand
grid-template
grid-template: row-length row-length / col-lengthis equivalent to…
grid-template-rows: row-length row-lengthgrid-template-columns: col-lengthHowever, prefer to use separate properties. They’re more readable and maintainable.
Implicit Tracks
If you place an item outside of the defined grid, CSS Grid will automatically create additional grid tracks to accommodate it.
By default, CSS Grid will add additional content with implicit rows. However, that can be changed by applying grid-auto-flow: column;.
Notably, the track sizes will not be applied to the implicit grid. But we can set implicit grid track sizes using the grid-auto-rows and grid-auto-columns properties.
For example, the below code will create an explicit 2x2 grid, but a fifth item added to the container will be automatically slotted into a third row— an implicit grid.
.container {
display: grid;
grid-template-rows: 50px 50px; /* Two 50px length rows */
grid-template-columns: 100px 100px; /* Two 100px length columns */
}The below code defines the implicit grid track row size:
.container {
display: grid;
grid-template-rows: 50px 50px;
grid-template-columns: 100px 100px;
grid-auto-rows: 75px; /* Sets the implicit grid track row size */
}Gap
The gap between grid rows and columns is known as the “gutter” or “alley.”
row-gap & column-gap properties can set the gap sizes.
gap is a shorthand property for setting both the row & column gaps, this is used most commonly.
.container {
display: grid;
grid-template-columns: 50px 50px;
grid-template-rows: 50px 50px;
gap: 4px 12px; /* row gap, column gap */
}Units (auto, fr, & more)
Various units can be used in grids:
- The usual:
em,rem,vw,vh,px, etc. - Percentages (%): Define sizes relative to the grid container’s size.
fr(fractional units): Distributes available space proportionally.- e.g.
1fr 2frdivides space into three parts, with second column taking 2x width.
- e.g.
auto
auto automatically takes up appropriate space.
- Row height sizes to fit its content. May collapse to 0 height if no minimum set.
- Column expands to fill available space after fixed-width columns are accounted for.
grid-template-rows: auto 40px auto;
grid-template-columns: 100px auto 100px;min-content & max-content
min-content: the smallest size a grid track can have without overflowing its contents.max-content: the largest size a grid track can have to fit its contents without causing overflow.
grid-template-columns: min-content max-content 1fr;Utility functions
Sizing functions
minmax(min, max): Sets minimum and maximum sizes for grid track.- Can only be used with
grid-template-rows,grid-auto-rows, & column equivalents.
- Can only be used with
clamp(minimum-size, ideal-size, maximum-size): allows item to resize until it reaches min or max threshold.fit-content(arg): Allows a grid track to grow to accommodate its content, up to a specified maximum.fit-content(100px): grows to accommodate content, but won’t exceed 100px.- It’s similar to
minmax(auto, max-content), but with an upper limit.
repeat()
repeat(count, track size): Useful helper for simplifying code.- e.g.
grid-auto-rows: repeat(2, 20px)is equivalent togrid-auto-rows: 20px 20px - Useful for dynamic columns:
repeat(auto-fit, minmax(100px, 1fr));
- e.g.
Dynamic columns: auto-fit and auto-fill
auto-fitandauto-filldynamically update the number of columns based on the grid size.- Both return the largest possible positive integer without the grid items overflowing their container.
- What’s the difference between the two?
auto-fill: Creates a fixed number of tracks based on the container width, regardless of the number of items. Some tracks may be empty.auto-fit: Creates only as many tracks as needed for the items and then expands these tracks to fill the container width. There are no empty tracks.
Auto-fill example: This creates a grid with a consistent number of columns that wraps to the next line when there’s not enough space. Each column will be at least 100px wide. The empty space to the right is actually empty columns.
.container {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}Auto-fit example: This creates a grid where items expand to fill the entire width of the container, with each item being at least 100px wide.
.container {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}Grid Area
Grid area allows you to define and name specific regions within your grid container.
Define areas using the grid-template-areas property on the grid container.
- Each string represents a row, each word represents a cell.
- Each ’.’ represents an empty cell.
The below is an example of a grid containing three named areas: header, sidebar, and content.
.container {
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-columns: 120px 1fr 1fr 1fr;
grid-template-areas:
'header header header header'
'sidebar main main .'
'footer footer footer footer';
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }grid-column / grid-row
grid-template-areas versus grid-column & grid-row
You can also place grid items using the
grid-columnandgrid-rowproperties. Both approaches are used equally by advanced developers.
The above grid area could have also been filled using the grid-column and grid-row properties:
When to use grid-template-areasversus grid-column / grid-row?
Prefer grid-template-areas for:
- Complex layouts: a visual representation that’s easier to conceptualize and maintain.
- Responsive design: allows for complete layout restructuring at different breakpoints by simply redefining the template using media queries.
Prefer grid-row / grid-column for:
- Numeric precision: when need items to span a specific number of grid tracks or align to exact gird lines.
- Dynamic content: if layout adapts to changing content or user interaction, it’s often easier to manipulate numeric values programmatically using JavaScript.
- Flexibility: for small adjustments, changing numeric values is often quicker and doesn’t require redefining the entire grid template.