CSS Grid Layout
- Two-dimensional layout control (rows AND columns),
- Precise placement of elements,
- Easy creation of complex layouts,
- Dynamic re-ordering of content based on media queries,
- Built-in support for responsive design,
- Reduced need for layout frameworks and extra markup.
To create a grid layout, you first need to define a container as a grid by applying the display: grid; or display: inline-grid; property to a parent element:
.container { display: grid;}.container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-gap: 20px; /* Adds gap between both rows and columns */}To set different gaps for rows and columns:
.container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-column-gap: 20px; grid-row-gap: 40px;}Use the grid-template-columns and grid-template-rows properties to define the size and number of columns and rows.
You can define fixed-size grid tracks (rows and columns) using various units:
.container { display: grid; grid-template-columns: 100px 200px 100px; grid-template-rows: 50px 100px;}This creates a grid with:
- Three columns of 100px, 200px, and 100px widths
- Two rows of 50px and 100px heights
The fr unit represents a fraction of the available space in the grid container:
.container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-template-rows: auto;}This creates a grid where:
- The total width is divided into 4 equal parts (1+2+1)
- The first column gets 1/4 of the space
- The second column gets 2/4 (or 1/2) of the space
- The third column gets 1/4 of the space
For large grids, you can use the repeat() function:
.container { display: grid; grid-template-columns: repeat(3, 1fr); /* Same as: 1fr 1fr 1fr */ grid-template-rows: repeat(2, 100px); /* Same as: 100px 100px */}The repeat() function takes two arguments:
- The number of times to repeat
- The pattern to repeat
The minmax() function defines a size range:
.container { display: grid; grid-template-columns: 1fr minmax(200px, 500px) 1fr;}This creates a middle column that:
- Will never be smaller than 200px
- Will never be larger than 500px
- Will grow and shrink within those constraints
For responsive design, auto-fill and auto-fit are useful:
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));}This creates as many 200px+ columns as can fit in the container.
Difference between auto-fill and auto-fit:
Section titled “Difference between auto-fill and auto-fit:”auto-fill: Creates as many tracks as possible, even if they’re emptyauto-fit: Collapses empty tracks and stretches existing tracks to fill the space
For implicitly created grid tracks:
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 100px; /* Any new rows will be 100px tall */}.container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-template-rows: auto;}1fr 2fr 1frmeans the grid will have three columns. The first and third columns will take 1 fraction of available space each, while the second column will take 2 fractions.automeans the row height will adjust automatically based on the content.
Once your grid is defined, you can position grid items using various methods:
Grid lines are automatically numbered starting from 1:
.item { grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4;}This places the item:
- From column line 1 to column line 3 (spanning 2 columns)
- From row line 2 to row line 4 (spanning 2 rows)
.item { grid-column: 1 / 3; /* Start at line 1, end at line 3 */ grid-row: 2 / 4; /* Start at line 2, end at line 4 */}Even shorter using the unified grid-area property:
.item { /* Format: row-start / column-start / row-end / column-end */ grid-area: 2 / 1 / 4 / 3;}.item { grid-column: 1 / span 2; /* Start at line 1 and span 2 columns */ grid-row: span 2 / 4; /* End at line 4 and span 2 rows upward */}You can count grid lines from the end using negative numbers:
.item { grid-column: 1 / -1; /* Spans from first line to last line */}You can also assign a name to grid areas and place grid items in those areas:
.container { display: grid; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; grid-template-areas: "header header header" "sidebar content aside" "footer footer footer"; height: 100vh;}
.header { grid-area: header; }.sidebar { grid-area: sidebar; }.content { grid-area: content; }.aside { grid-area: aside; }.footer { grid-area: footer; }This creates a classic page layout with header, footer, main content and sidebars.
You can leave cells empty using a period (.):
grid-template-areas: "header header header" "sidebar content . " "footer footer footer";In this example, the top-right cell in the middle row is left empty.
CSS Grid has powerful alignment capabilities, divided into two categories:
.container { /* Horizontal alignment */ justify-items: start | end | center | stretch;
/* Vertical alignment */ align-items: start | end | center | stretch;
/* Shorthand for both */ place-items: <align-items> <justify-items>;}.item { justify-self: start | end | center | stretch; align-self: start | end | center | stretch; place-self: <align-self> <justify-self>;}Aligning the Grid Tracks Within the Container
Section titled “Aligning the Grid Tracks Within the Container”If the grid tracks don’t use all available space:
.container { /* Horizontal alignment of all tracks */ justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
/* Vertical alignment of all tracks */ align-content: start | end | center | stretch | space-around | space-between | space-evenly;
/* Shorthand for both */ place-content: <align-content> <justify-content>;}Example: Responsive 2-Column to 1-Column Layout
Section titled “Example: Responsive 2-Column to 1-Column Layout”.container { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 20px;}
@media (max-width: 768px) { .container { grid-template-columns: 1fr; /* Switches to 1 column layout */ }}.container { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px;}This creates a responsive grid where:
- Each column is at least 250px wide
- Columns expand to fill available space
- The number of columns adjusts automatically as the viewport changes
.container { display: grid; grid-template-columns: 1fr; grid-template-areas: "header" "content" "sidebar" "footer";}
@media (min-width: 768px) { .container { grid-template-columns: 200px 1fr; grid-template-areas: "header header" "sidebar content" "footer footer"; }}
@media (min-width: 1024px) { .container { grid-template-columns: 200px 1fr 200px; grid-template-areas: "header header header" "sidebar content aside" "footer footer footer"; }}Grid and Flexbox are complementary, not competing layout systems. Here’s when to use each:
- Creating two-dimensional layouts (rows AND columns)
- Working with the overall page layout
- Precise placement of elements is needed
- Creating complex, asymmetrical layouts
- Designing from the “outside in” (defining the container first)
- Creating one-dimensional layouts (either rows OR columns)
- Distributing space among elements of unknown size
- Aligning items within a container
- Working with content flow rather than explicit placement
- Designing from the “inside out” (letting the content dictate the layout)