CSS Grid Layout

CSS Grid Layout

A Complete Guide to CSS Grid

·

13 min read

CSS Grid Layout excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer, between parts of a control built from HTML primitives.

Like tables, grid layout enables an author to align elements into columns and rows. However, many more layouts are either possible or easier with CSS grid than they were with tables. For example, a grid container's child elements could position themselves so they actually overlap and layer, similar to CSS-positioned elements.

Grid Terminology

Grid Container

The element on which display: grid is applied. It’s the direct parent of all the grid items. In this example, container is the grid container.

<div class="container">
  <div class="item item-1"> </div>
  <div class="item item-2"> </div>
  <div class="item item-3"> </div>
</div>

Grid Line

The dividing lines make up the structure of the grid. They can be either vertical (“column grid lines”) or horizontal (“row grid lines”) and reside on either side of a row or column. Here the yellow line is an example of a column grid line.

Grid Track

The space between two adjacent grid lines. You can think of them as the columns or rows of the grid. Here’s the grid track between the second and third-row grid lines.

Grid Area

The total space is surrounded by four grid lines. A grid area may be composed of any number of grid cells. Here are the grid area between row grid lines 1 and 3, and column grid lines 1 and 3.

Grid Item

The children (i.e. direct descendants) of the grid container. Here the item elements are grid items but sub-item aren’t.

<div class="container">
  <div class="item"> </div>
  <div class="item">
    <p class="sub-item"> </p>
  </div>
  <div class="item"> </div>
</div>

Grid Cell

The space between two adjacent rows and two adjacent column grid lines. It’s a single “unit” of the grid. Here are the grid cell between row grid lines 1 and 2, and column grid lines 2 and 3.

Grid Properties

Properties for the Parent (Grid Container)

  1. Display

    Defines the element as a grid container and establishes a new grid formatting context for its contents.

    Values:

    • grid – generates a block-level grid

    • inline-grid – generates an inline-level grid

       .container {
         display: grid | inline-grid;
       }
      
  2. grid-template-columns & grid-template-rows

    Defines the columns and rows of the grid with a space-separated list of values. The values represent the track size, and the space between them represents the grid line.

    Values:

    • <track-size> – can be a length, a percentage, or a fraction of the free space in the grid using the fr unit.
    • <line-name> – an arbitrary name of your choosing.

      .container { 
           grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line]; 
      }
      

      Grid lines are automatically assigned positive numbers from these assignments (-1 being an alternate for the last row). But you can choose to explicitly name the lines. Note the bracket syntax for the line names in the above example. Note that a line can have more than one name. For example, the second line will have two names: row1-end and row2-start. If your definition contains repeating parts, you can use the repeat() notation to streamline things:

      .container {
        grid-template-columns: repeat(3, 20px [col-start]); 
      } 
      /* Which is equivalent to */ 
      .container {
       grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start]; 
      }
      

    The fr unit allows you to set the size of a track as a fraction of the free space of the grid container. For example, this will set each item to one-third the width of the grid container:

    .container { grid-template-columns: 1fr 1fr 1fr; }
    
  3. grid-template-area

    Defines a grid template by referencing the names of the grid areas which are specified with the grid-area property. Repeating the name of a grid area causes the content to span those cells. A period signifies an empty cell. The syntax itself provides a visualization of the structure of the grid.

    Values:

    • <grid-area-name> – the name of a grid area specified with grid-area
    • . – a period signifies an empty grid cell
    • none – no grid areas are defined

      .container {
      grid-template-areas: 
      "<grid-area-name> | . | none | ..."
      "...";
      }
      

      For Example:

      .item-a {
      grid-area: header;
      }
      .item-d {
      grid-area: footer;
      }
      .container {
      display: grid;
      grid-template-columns: 50px 50px 50px 50px;
      grid-template-rows: auto;
      grid-template-areas: 
      "header header header header"
      "footer footer footer footer";
      }
      

      That’ll create a grid that’s four columns wide by three rows tall. The entire top row will be composed of the header area. The last row is all footer.

  4. grid-template

    Shorthand for setting grid-template-rows, grid-template-columns, and grid-template-areas in a single declaration.

    Values:

    • none – sets all three properties to their initial values
    • <grid-template-rows> / <grid-template-columns> – sets grid-template-columns and grid-template-rows to the specified values, respectively, and sets grid-template-areas to none
    .container {
       grid-template: none | <grid-template-rows> / <grid-template-columns>;
    }
    

    Example:

    .container {
     grid-template:
     [row1-start] "header header header" 25px [row1-end]
     [row2-start] "footer footer footer" 25px [row2-end]
     / auto 50px auto;
    }
    

    Since grid-template doesn’t reset the implicit grid properties (grid-auto-columns, grid-auto-rows, and grid-auto-flow), which is probably what you want to do in most cases, it’s recommended to use the grid property instead of grid-template.

  5. column-gap, row-gap, grid-column-gap, grid-row-gap

    Specifies the size of the grid lines. You can think of it as setting the width of the gutters between the columns/rows.

    Values:

    • <line-size> – a length value

      The gutters are only created between the columns/rows, not on the outer edges.

      .container {
      /* standard */
      column-gap: <line-size>;
      row-gap: <line-size>;
      /* old */
      grid-column-gap: <line-size>;
      grid-row-gap: <line-size>;
      }
      

      Example:

      .container {
      grid-template-columns: 100px 50px 100px;
      grid-template-rows: 80px auto 80px; 
      column-gap: 10px;
      row-gap: 15px;
      }
      
  6. gap, grid-gap

    A shorthand for row-gap and column-gap

    Values:

    • <grid-row-gap> <grid-column-gap> – length values

      If no row-gap is specified, it’s set to the same value as column-gap

      .container {
      /* standard */
      gap: <grid-row-gap> <grid-column-gap>;
      /* old */
      grid-gap: <grid-row-gap> <grid-column-gap>;
      }
      

      Example:

      .container {
        grid-template-columns: 100px 50px 100px;
        grid-template-rows: 80px auto 80px; 
        gap: 15px 10px;
      }
      
  7. justify-items

    Aligns grid items along the inline (row) axis (as opposed to align-items which align along the block (column) axis). This value applies to all grid items inside the container.

    Values:

    • start – aligns items to be flush with the start edge of their cell
    • end – aligns items to be flush with the end edge of their cell
    • center – aligns items in the center of their cell
    • stretch – fills the whole width of the cell (this is the default)

      .container {
         justify-items: start | end | center | stretch;
      }
      

  8. align-items

    Aligns grid items along the block (column) axis (as opposed to justify-items which aligns along the inline (row) axis). This value applies to all grid items inside the container.

    Values:

    • stretch – fills the whole height of the cell (this is the default)
    • start – aligns items to be flush with the start edge of their cell
    • end – aligns items to be flush with the end edge of their cell
    • center – aligns items in the center of their cell
    • baseline – align items along text baseline.

      There are modifiers to baseline — first baseline and last baseline which will use the baseline from the first or last line in the case of multi-line text.

      .container {
        align-items: start | end | center | stretch;
      }
      

  9. place-items

    place-items sets both the align-items and justify-items properties in a single declaration.

    Values:

    • <align-items> / <justify-items> – The first value sets align-items, and the second value justify-items. If the second value is omitted, the first value is assigned to both properties.

      This can be very useful for super quick multi-directional centering:

      .center { 
        display: grid; 
        place-items: center; 
      }
      
  10. justify-content

    Sometimes the total size of your grid might be less than the size of its grid container. This could happen if all of your grid items are sized with non-flexible units like px. In this case, you can set the alignment of the grid within the grid container. This property aligns the grid along the inline (row) axis (as opposed to align-content which aligns the grid along the block (column) axis).

    Values:

    • start – aligns the grid to be flush with the start edge of the grid container
    • end – aligns the grid to be flush with the end edge of the grid container
    • center – aligns the grid in the center of the grid container
    • stretch – resizes the grid items to allow the grid to fill the full width of the grid container
    • space-around – places an even amount of space between each grid item, with half-sized spaces on the far ends
    • space-between – places an even amount of space between each grid item, with no space at the far ends
    • space-evenly – places an even amount of space between each grid item, including the far ends
    .container {
       justify-content: start | end | center | stretch | space-around | space-between | space-evenly;    
    }
    

  11. align-content

    This property aligns the grid along the block (column) axis (as opposed to justify-content which aligns the grid along the inline (row) axis).

    Values:

    • start – aligns the grid to be flush with the start edge of the grid container
    • end – aligns the grid to be flush with the end edge of the grid container
    • center – aligns the grid in the center of the grid container
    • stretch – resizes the grid items to allow the grid to fill the full height of the grid container
    • space-around – places an even amount of space between each grid item, with half-sized spaces on the far ends
    • space-between – places an even amount of space between each grid item, with no space at the far ends
    • space-evenly – places an even amount of space between each grid item, including the far ends

      .container {
          align-content: start | end | center | stretch | space-around | space-between | space-evenly;    
      }
      
  12. place-content

    place-content sets both the align-content and justify-content properties in a single declaration. All major browsers except Edge support the place-content shorthand property.

    Values:

    • <align-content> / <justify-content> – The first value sets align-content, and the second value justify-content. If the second value is omitted, the first value is assigned to both properties.
  13. grid-auto-columns, grid-auto-rows

    Specifies the size of any auto-generated grid tracks (aka implicit grid tracks). Implicit tracks get created when there are more grid items than cells in the grid or when a grid item is placed outside of the explicit grid. (see The Difference Between Explicit and Implicit Grids)

    Values:

    • <track-size> – can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit).
    .container {
        grid-auto-columns: <track-size> ...;
        grid-auto-rows: <track-size> ...;
    }
    
  14. grid-auto-flow

    If you have grid items that you don’t explicitly place on the grid, the auto-placement algorithm kicks in to automatically place the items. This property controls how the auto-placement algorithm works.

    Values:

    • row – tells the auto-placement algorithm to fill in each row in turn, adding new rows as necessary (default)
    • column – tells the auto-placement algorithm to fill in each column in turn, adding new columns as necessary
    • dense – tells the auto-placement algorithm to attempt to fill in holes earlier in the grid if smaller items come up later. dense only changes the visual order of your items and might cause them to appear out of order, which is bad for accessibility.
    .container {
        grid-auto-flow: row | column | row dense | column dense;
    }
    
  15. grid

    Shorthand for setting all of the following properties in a single declaration: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, and grid-auto-flow (Note: You can only specify the explicit or the implicit grid properties in a single grid declaration).

    Values:

    • none – sets all sub-properties to their initial values.
    • <grid-template> – works the same as the grid-template shorthand.
    • <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>? – sets grid-template-rows to the specified value. If the auto-flow keyword is to the right of the slash, it sets grid-auto-flow to the column. If the dense keyword is specified additionally, the auto-placement algorithm uses a “dense” packing algorithm. If grid-auto-columns is omitted, it is set to auto.
    • [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> – sets grid-template-columns to the specified value. If the auto-flow keyword is to the left of the slash, it sets grid-auto-flow to row. If the dense keyword is specified additionally, the auto-placement algorithm uses a “dense” packing algorithm. If grid-auto-rows is omitted, it is set to auto.
    • [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> – sets grid-template-columns to the specified value. If the auto-flow keyword is to the left of the slash, it sets grid-auto-flow to row. If the dense keyword is specified additionally, the auto-placement algorithm uses a “dense” packing algorithm. If grid-auto-rows is omitted, it is set to auto.
    .container {
        grid: auto-flow dense 100px / 1fr 2fr;
    }
    /* above code is equivalent to below */
    .container {
       grid-auto-flow: row dense;
       grid-auto-rows: 100px;
       grid-template-columns: 1fr 2fr;
    }
    

Properties for the Children (Grid Items)

  1. grid-column-start, grid-column-end, grid-row-start, grid-row-end

    Determines a grid item’s location within the grid by referring to specific grid lines. grid-column-start/grid-row-start is the line where the item begins, and grid-column-end/grid-row-end is the line where the item ends.

    Values:

    • <line> – can be a number to refer to a numbered grid line, or a name to refer to a named grid line
    • span <number> – the item will span across the provided number of grid tracks
    • span <name> – the item will span across until it hits the next line with the provided name
    • auto – indicates auto-placement, an automatic span, or a default span of one

      .item {
      grid-column-start: <number> | <name> | span <number> | span <name> | auto;
      grid-column-end: <number> | <name> | span <number> | span <name> | auto;
      grid-row-start: <number> | <name> | span <number> | span <name> | auto;
      grid-row-end: <number> | <name> | span <number> | span <name> | auto;
      }
      

      Example:

      .item-a {
       grid-column-start: 2;
       grid-column-end: five;
       grid-row-start: row1-start;
       grid-row-end: 3;
      }
      
  2. grid-column, grid-row

    Shorthand for grid-column-start + grid-column-end, and grid-row-start + grid-row-end, respectively.

    Values:

    • <start-line> / <end-line> – each one accepts all the same values as the longhand version, including span.

      If no end line value is declared, the item will span 1 track by default.

      .item {
       grid-column: <start-line> / <end-line> | <start-line> / span <value>;
       grid-row: <start-line> / <end-line> | <start-line> / span <value>;
      }
      

      Example:

      .item-c {
        grid-column: 3 / span 2;
        grid-row: third-line / 4;
      }
      
  3. grid-area

    Gives an item a name so that it can be referenced by a template created with the grid-template-areas property. Alternatively, this property can be used as an even shorter shorthand for grid-row-start + grid-column-start + grid-row-end + grid-column-end.

    Values:

    • <name> – a name of your choosing
    • <row-start> / <column-start> / <row-end> / <column-end> – can be numbers or named lines
    .item {
      grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
    }
    
  4. justify-self

    Aligns a grid item inside a cell along the inline (row) axis (as opposed to align-self which aligns along the block (column) axis). This value applies to a grid item inside a single cell.

    Values:

    • start – aligns the grid item to be flush with the start edge of the cell
    • end – aligns the grid item to be flush with the end edge of the cell
    • center – aligns the grid item in the center of the cell
    • stretch – fills the whole width of the cell (this is the default)
    .item {
       justify-self: start | end | center | stretch;
    }
    
  5. align-self

    Aligns a grid item inside a cell along the block (column) axis (as opposed to justify-self which aligns along the inline (row) axis). This value applies to the content inside a single grid item.

    Values:

    • start – aligns the grid item to be flush with the start edge of the cell
    • end – aligns the grid item to be flush with the end edge of the cell
    • center – aligns the grid item in the center of the cell
    • stretch – fills the whole height of the cell (this is the default)
    .item {
       align-self: start | end | center | stretch;
    }
    
  6. place-self

    place-self sets both the align-self and justify-self properties in a single declaration.

    Values:

    • auto – The “default” alignment for the layout mode.
    • <align-self> / <justify-self> – The first value sets align-self, and the second value justify-self. If the second value is omitted, the first value is assigned to both properties.

      .item-a {
         place-self: center | center stretch;
      }
      

Thank you

If you enjoyed this article

Follow me on Linked In