CK

CSS Grid cheat-sheet

Oops!

Your browser does not support CSS Grid!

CSS Grid is one of the best ways to build layouts because it is a two dimensional layout system, it uses columns and rows. This cheat-sheet aims to explain some of the basics with examples, feel free to use your browsers dev tools to inspect the example above each snippet.

Defining A Fixed Grid

Below we have 8 items (div), to begin we will apply our grid layout using display: grid; and then use grid-template-columns to create our columns and grid-template-rows for our rows. Any items outside of our defined columns and rows will use our implicit grid (they will be part of our layout automatically) and sized using grid-template-rows.

1
2
3
4
5
6
7
8
      .container {
        /* apply grid layout */
        display: grid;

        /* three columns at 200px each */
        grid-template-columns: 200px 200px 200px;

        /* two rows at 200px and 50px */
        grid-template-rows: 200px 50px;

        /* set rows without an implicit size to 100px */
        grid-auto-rows: 100px;

        /* gap between columns to 20px */
        grid-column-gap: 20px;

        /* gap between rows 20px */
        grid-row-gap: 20px;

        /* shorthand to set gap between columns and rows to 20px */
        /* grid-gap: 20px; */
      }
    

Introducing the 'fr' unit

The 'fr' unit can be used for flexible grids, 'fr' is a fraction of space within the grid container. So when we write grid-template-columns: 1fr 1fr 1fr; we are creating three columns of equal size that will change based on the viewport size. An 'fr' column will also resize around a fixed column.

1
2
3
4
5
6
7
8
      .container {
        display: grid;

        /* three responsive columns using 1fr each */
        grid-template-columns: 1fr 1fr 1fr;

        grid-gap: 20px;
      }
    

Repeat function

If our grid has repeating patterns we can use repeat() to create multiple columns at once or even repeat a set of columns.

1
2
3
4
5
6
7
8
      .container {
        display: grid;

        /* repeating two columns of 2fr and 1fr four times */
        grid-template-columns: repeat(4, 2fr 1fr);

        /* fixed column of 500px and repeating two columns of 2fr and 1fr twice */
        /*grid-template-columns: 500px repeat(2, 2fr 1fr); */

        grid-gap: 20px;
      }
    

Minmax function

With minmax() we can specify the minimum and maximum size of a grid track. So, if we want our rows to always be at least 50px in height but still resize based on content we can write grid-auto-rows: minmax(50px, auto);.

1

Hello World

2
3
4
5
6
7
8
      .container {
        display: grid;

        /* a column with min width of 200px, max of 250px, and two columns of 1fr */
        grid-template-columns: minmax(200px, 250px) 1fr 1fr;

        /* size of rows that have not been implicitly set, minimum 50px, maximum auto - will size relative to content */
        grid-auto-rows: minmax(50px, auto);

        grid-gap: 20px;
      }
    

Location and Span

We can build our grid using our items to create implicit rows and then move or scale them using grid-column-start and grid-row-start to define where the item starts then grid-column-end and grid-row-end to define where the item ends. We can also write this in shorthand using grid-column and grid-row.

1
2
3
4
5
6
7
8
      .container {
        grid-template-columns: repeat(8, 1fr);
        grid-auto-rows: minmax(50px, auto);
        grid-gap: 5px;
      }

      /* second item selector  */
      .item:nth-child(2) {
        /* start item from column 2 */
        grid-column-start: 2;

        /* end item on span of 2 columns */
        grid-column-end: span 2;

        /* start item on row 1 */
        grid-row-start: 1;

        /* end item on span of 2 rows */
        grid-row-end: span 2;
      }

      /* fourth item selector */
      .tem:nth-child(4) {
        /* start item from column 5*/
        grid-column-start: 5;

        /* start item on span of 3 rows */
        grid-row-start: span 3;
      }

      /* eight item selector */
      .item:nth-child(8) {
        /* move item to row 4 */
        grid-row: 4;

        /* start item on column 1 and end on last column (-1) */
        grid-column: 1 / -1;
      }
    

Auto-placement

A grid will place it's items automatically in rows unless we define the flow, we can change the flow with grid-auto-flow: column; to place items by column instead.

1
2
3
4
5
6
7
8
      .container {
        display: grid;
        grid-template-columns: repeat(4, 1fr);

        /* place elements in order of columns */
        grid-auto-flow: column;

        /* place elements in order of rows */
        /*grid-auto-flow: row;*/

        grid-template-rows: repeat(2, minmax(100px, auto));
        grid-gap: 20px;
      }
    

Dense

Along with column and row we can use the 'dense' keyword, grid-auto-flow: dense; will attempt to fill in gaps earlier in the grid if smaller items come up later.

1
2
4
7
8
10
13
14
16
19
20
21
22
23
24
25
26
      .container {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
        grid-auto-rows: minmax(80px, auto);
        grid-gap: 2px;

        /* Dense will fill the gaps in the grid */
        grid-auto-flow: dense;
      }
      .red {
        grid-column-end: span 3;
        grid-row-end: span 3;
      }
      .orange {
        grid-column-end: span 2;
        grid-row-end: span 2;
      }
      .blue {
        grid-row-end: span 3;
      }
    
    

Order

We can change the order of the elements displayed in the grid, if we want our first item in the DOM to be last in the grid then we would set all the items to order: 1; and our first item to order: 2;. However, changing the order of an element in CSS does not change it in the DOM, consider this when styling tabbed elements etc.

1
2
3
4
5
6
7
8
      .container {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        grid-template-rows: repeat(2, minmax(100px, auto));
        grid-gap: 20px;
      }

      /* order second child as 1 */
      .item:nth-child(2) {
        order: 1;
      }

      /* set order of other items to below second child */
      .item {
        order: 2;
      }
    

Auto-fill

Using auto-fill will create as many tracks as will fit in to the container, any empty tracks will remain part of the grid. So we have 8 items below but because we have used auto-fill with a minimum column size of 50px we have space left over because auto-fill has created tracks that we do not have content for.

1
2
3
4
5
6
7
8
      .container {
        display: grid;

        /* repeat as many columns as will fit in container at a minimum size of 50px and max of 1fr */
        grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));

        grid-gap: 20px;
      }
    

Auto-fit

Using auto-fit will create as many tracks as will fit in to the container but, unlike auto-fill, it will drop any empty tracks and fill the rest of the space left behind. So our 8 items now fill the tracks created and any empty tracks are gone, leaving the 8 to fill the container.

1
2
3
4
5
6
7
8
      .container {
        display: grid;

        /* repeat as many columns as will fit in container at a minimum size of 80px and max of 1fr AND drop any empty items */
        grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));

        grid-auto-rows: minmax(80px, auto);
        grid-gap: 5px;
      }
    

Named lines

Instead of using numbers to define where our items are placed, start and end we can define lines that draw out boundaries throughout our grid. grid-template-columns: [content-start] 1fr [content-end]; creates one flexible column with named lines at the beginning and the end of the column. So when we write grid-column: content-start; on an item we are saying we want that item to begin/move to the column named line 'content-start'. Use named lines to define the lines between content and change their placement with media queries.

Red
Blue
Orange
      .container {
        display: grid;
        /* define 'content-start' line, one column of 1fr, and define 'content-end line */
        grid-template-columns: [content-start] 1fr [content-end];

        /* one row of auto, define 'content-start' line, one row of auto, and define 'content-end' line */
        grid-template-rows: auto [content-start] auto [content-end];

        grid-gap: 20px;
      }
      @media (min-width: 640px) {
        .container {
          /* one column of 2fr, define 'content-start' line, one columne of 4fr, and define 'content-end' line */
          grid-template-columns: 2fr [content-start] 4fr [content-end];
        }
      }
      .orange {
        /* place grid-column from 'content-start' line */
        grid-column: content-start;

        /* place grid-row from 'content-start' line */
        grid-row: content-start;
      }
    

Aligning and justifying content/items

Like flex we can align content and grid items relative to rows and columns.

1
2
3
4
5
6
      .container {
        display: grid;
        height: 300px;
        grid-template-columns: 150px 150px 150px;
        grid-auto-rows: minmax(100px, auto);
        grid-gap: 20px;

        /* align content along row axis */
        justify-content: center;

        /* align content along column axis */
        align-content: center;

        /* align items within their grid layout along row axis */
        justify-items: stretch;

        /* align items within their grid layout along column axis */
        align-items: stretch;
      }
    
/>

Grid template areas

Another way to build a layout is using grid-template-areas. We can assign items grid-areas, so grid-area: rd; will assign the item grid-area to "rd", we can then build out our layout using grid-template-areas:"rd";. With multiple items assigned grid-areas the layout can be shaped and our items can span across columns and rows using ascii-style grid-template-areas.

1
2
3
4
      .red {
        /* grid area name of rd */
        grid-area: rd;
      }
      .blue {
        /* grid area name of bl */
        grid-area: bl;
      }
      .black {
        /* grid area name of pr */
        grid-area: bk;
      }
      .orange {
        /* grid area name of og */
        grid-area: og;
      }
      .container {
        display: grid;
        grid-auto-rows: minmax(100px, auto);
        grid-gap: 20px;

        /* create grid template use defined items */
        grid-template-areas:
          "rd"
          "bl"
          "bk"
          "og";
      }
      @media (min-width: 640px) {
        .container {
          grid-template-columns: 1fr 4fr 1fr;

          /* place items in grid template according to area layout */
          grid-template-areas:
            "rd  bl bk"
            "rd bl bk"
            "og og og";
        }
      }