DEV Community

Cover image for Delve into CSS Grid and Flexbox
Eric Hu
Eric Hu

Posted on • Originally published at ericsdevblog.com

Delve into CSS Grid and Flexbox

Creating layouts using CSS is one of the most fundamental skills a web developer must possess. A well-designed layout is the backbone of any successful website, as it improves user experience, visual appeal, and overall usability. There are two ways you can create a webpage layout using CSS, either with grids or the flexbox. Let's start with the traditional method and discuss how to create a grid layout.

📧 Subscribe to my newsletter: https://ericsdevblog.ck.page/profile

Creating grids

A grid layout consists of a grid container and several grid items. The grid container must have its display property set to grid or inline-grid. grid creates a block-level grid container, and inline-grid creates an inline-level grid container.

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.container {
  display: grid;
}
Enter fullscreen mode Exit fullscreen mode

All direct children of this container will automatically become grid items.

Grid columns and rows

You can then specify how many columns you wish to create using the grid-template-columns property. The property accepts any number of values. The number of values determines the number of columns, and the value itself determines the size of that column. For example:

.container {
  display: grid;
  grid-template-columns: 100px 200px;
}

.item {
  font-family: Georgia, 'Times New Roman', Times, serif;
  font-size: x-large;
  text-align: center;
  padding: 20px;
  border: 1px solid orange;
  background-color: bisque;
}
Enter fullscreen mode Exit fullscreen mode

grid with two columns

I also added some styles for the grid items to make the grid look more pleasing, but it is not necessary here, so I will omit them in future examples.

.container {
  display: grid;
  grid-template-columns: 100px 200px 50px;
}
Enter fullscreen mode Exit fullscreen mode

grid with three columns

If you want all columns to have equal size, simply set the values to auto.

grid with auto columns

Similarly, you can specify row sizes using the grid-template-rows property.

.container {
  display: grid;
  grid-template-columns: auto auto auto;
  grid-template-rows: 100px 150px;
}
Enter fullscreen mode Exit fullscreen mode

grid with different row heights

However, this property does not determine the number of rows in the grid. If you specify extra values, they will be ignored.

Lastly, grid-template is a shorthand property for grid-template-columns and grid-template-rows with the following syntax:

grid-template: <row> <row> ... / <col> <col> ...;
Enter fullscreen mode Exit fullscreen mode
.container {
  display: grid;
  grid-template: 100px 150px / auto auto auto;
}
Enter fullscreen mode Exit fullscreen mode

grid template

Grid gaps

When designing a webpage, it is good to leave some space between elements so that they are not too close to each other. By using the grid layout, you can easily add equal spacing between all grid items instead of micromanaging each margin. For example:

.container {
  display: grid;
  grid-template-columns: auto auto auto;
  row-gap: 10px;
  column-gap: 20px;
}
Enter fullscreen mode Exit fullscreen mode

gaps

Alternatively, you may use the shorthand property, gap:

.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px 20px;
}
Enter fullscreen mode Exit fullscreen mode

If you want equal spacing for column gaps and row gaps, specify a single value:

.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

gaps with equal spacing

Grid items

It is also possible for you to customize individual grid items using CSS. In a real-life scenario, it is common for one grid item to take up multiple columns or rows. For example, you can define an item to span across multiple columns by specifying a start point (grid-column-start) and an end point (grid-column-end).

<div class="container">
    <div class="item-2col">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
}

.item {
  . . .
}

.item-2col {
  grid-column-start: 1;
  grid-column-end: 3;
}
Enter fullscreen mode Exit fullscreen mode

grid item two columns

Keep in mind that the numbers refer to the column lines, not columns, as shown in the chart below.

column lines and row lines

So, for an item to span across two columns, it should start from 1 and end with 3.

You can also use the shorthand property grid-column to achieve the same result:

.item-2col {
  grid-column: 1 / 3;
}
Enter fullscreen mode Exit fullscreen mode

Similarly, you can define a grid item to span across multiple rows using the grid-row-start and grid-row-end properties, or the grid-row shorthand.

.item-2row {
  grid-row-start: 1;
  grid-row-end: 3;
}
Enter fullscreen mode Exit fullscreen mode
.item-2row {
  grid-row: 1 / 3;
}
Enter fullscreen mode Exit fullscreen mode

grid row

If an item needs to span across multiple rows and columns, you can use the grid-area property instead, which is a shorthand for grid-row and grid-column. It has the following syntax:

grid-area: <row_start> / <col_start> / <row_end> / <col_end>
Enter fullscreen mode Exit fullscreen mode
.item-area {
  grid-area: 1 / 1 / 3 / 3;
}
Enter fullscreen mode Exit fullscreen mode

grid area

Grid alignment

Just like aligning individual elements in a webpage, when aligning items in a grid, we also have to talk about horizontal and vertical directions. However, things are a bit more complex than that. There are six different alignment properties, as shown in the list below:

  • align-content
  • align-items
  • align-self
  • justify-content
  • justify-items
  • justify-self

Vertical alignment

Let's discuss each of them one by one. First of all, the align properties control vertical alignment. As an example, this is a grid with six items, and the grid container is 300px high:

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
  height: 300px;
}
Enter fullscreen mode Exit fullscreen mode

The align-content property is used to specify the alignment of rows when there is available space in the container. Common values include:

  • start
  .container {
    align-content: start;
  }
Enter fullscreen mode Exit fullscreen mode

align content start

  • end
  .container {
    align-content: end;
  }
Enter fullscreen mode Exit fullscreen mode

align content end

  • center
  .container {
    align-content: center;
  }
Enter fullscreen mode Exit fullscreen mode

align content center

  • space-between
  .container {
    align-content: space-between;
  }
Enter fullscreen mode Exit fullscreen mode

align content space between

  • space-around
  .container {
    align-content: space-around;
  }
Enter fullscreen mode Exit fullscreen mode

align content space around

  • space-evenly
  .container {
    align-content: space-evenly;
  }
Enter fullscreen mode Exit fullscreen mode

align content space evenly

  • stretch
  .container {
    align-content: stretch;
  }
Enter fullscreen mode Exit fullscreen mode

align content stretch

align-items, on the other hand, is used to align individual grid items within their respective grid cells along the block axis. This is especially useful when grid items have different heights. Common values include:

  • start
  .container {
    align-items: start;
  }
Enter fullscreen mode Exit fullscreen mode

align items start

  • end
  .container {
    align-items: end;
  }
Enter fullscreen mode Exit fullscreen mode

align items end

  • center
  .container {
    align-items: center;
  }
Enter fullscreen mode Exit fullscreen mode

align items center

  • stretch
  .container {
    align-items: stretch;
  }
Enter fullscreen mode Exit fullscreen mode

align items stretch

  • baseline
  .container {
    align-items: baseline;
  }
Enter fullscreen mode Exit fullscreen mode

align items baseline

Lastly, the align-self property works just like align-items, except it is used on individual grid cells, not the container. It will overwrite the alignment rule set by align-items.

.container {
  align-items: start;
}

.item-sm {
  align-self: end;
}
Enter fullscreen mode Exit fullscreen mode

align self

Horizontal alignment

The horizontal alignment, controlled by the justify properties, works in a similar way. First, the justify-content property defines how grid items are distributed horizontally along the main axis. Some common values are:

  • start
  .container {
    justify-content: start;
  }
Enter fullscreen mode Exit fullscreen mode

justify content start

  • end
  .container {
    justify-content: end;
  }
Enter fullscreen mode Exit fullscreen mode

justify content end

  • center
  .container {
    justify-content: center;
  }
Enter fullscreen mode Exit fullscreen mode

justify content center

  • space-between
  .container {
    justify-content: space-between;
  }
Enter fullscreen mode Exit fullscreen mode

justify content between

  • space-around
  .container {
    justify-content: space-around;
  }
Enter fullscreen mode Exit fullscreen mode

justify content around

  • space-evenly
  .container {
    justify-content: space-evenly;
  }
Enter fullscreen mode Exit fullscreen mode

justify content evenly

The justify-items controls how grid items are aligned horizontally within their cells. Some common values are:

  • start
  .container {
    justify-items: start;
  }
Enter fullscreen mode Exit fullscreen mode

justify items start

  • end
  .container {
    justify-items: end;
  }
Enter fullscreen mode Exit fullscreen mode

justify items end

  • center
  .container {
    justify-items: center;
  }
Enter fullscreen mode Exit fullscreen mode

justify items center

  • stretch
  .container {
    justify-items: stretch;
  }
Enter fullscreen mode Exit fullscreen mode

justify items stretch

Similarly, the justify-self property is used on individual grid items to overwrite the default alignment rule set by justify-items.

.container {
  justify-items: start;
}

.item-sm {
  justify-self: end;
}
Enter fullscreen mode Exit fullscreen mode

justify self

Flexbox layout

The flexbox is another layout model in CSS that provides an efficient way to design and structure complex layouts, but with a more flexible approach. It is particularly suited for creating one-dimensional layouts, either in a row or a column, as we will see later.

Just like a grid layout, a flexbox layout also consists of a flex container and several flex items. The container should have its display property set to flex, and all its direct children automatically become flex items.

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.container {
  display: flex;
  gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

With a flex layout, instead of rows and columns, you must define a flex-direction and a flex-wrap. The flex-direction specifies in which direction the container should stack its flex items. The accepted values are:

  • column
  .container {
    flex-direction: column;
  }
Enter fullscreen mode Exit fullscreen mode

flex direction column

  • column-reverse
  .container {
    flex-direction: column-reverse;
  }
Enter fullscreen mode Exit fullscreen mode

flex direction column reverse

  • row
  .container {
    flex-direction: row;
  }
Enter fullscreen mode Exit fullscreen mode

flex direction row

  • row-reverse
  .container {
    flex-direction: row-reverse;
  }
Enter fullscreen mode Exit fullscreen mode

flex direction row reverse

The flex-wrap property determines whether the flex items should wrap (automatically change to the following line when there is insufficient space).

  • wrap
  .container {
    flex-wrap: wrap;
  }
Enter fullscreen mode Exit fullscreen mode

flex wrap

  • nowrap
  .container {
    flex-wrap: nowrap;
  }
Enter fullscreen mode Exit fullscreen mode

flex nowrap

  • wrap-reverse
  .container {
    flex-wrap: wrap-reverse;
  }
Enter fullscreen mode Exit fullscreen mode

flex wrap reverse

The flex-flow is a shorthand for flex-direction and flex-wrap properties.

.container {
  flex-flow: column wrap;
}
Enter fullscreen mode Exit fullscreen mode

flex flow

Lastly, the alignment properties for the grid layout we discussed before also work for flexbox layouts. For example:

.container {
  flex-direction: row;
  flex-wrap: wrap;

  align-content: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

flex alignment

Next steps

In this article, we explored gird and flexbox, two primary methods you can use to create webpage layouts. In the next article, we will discuss how to use the knowledge we've learned so far to create layouts that work for different screen sizes. This design principle is referred to as responsive design.

If you are interested, here are some of my other articles about CSS and frontend design:

Top comments (0)