Delve into CSS Grid and Flexbox
Tags: html, css, webdev, tutorial
Published: 2023-10-30 15:45:02

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.

```html
<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>
```

```css
.container {
  display: grid;
}
```

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:

```css
.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;
}
```

![grid with two columns](https://www.ericsdevblog.com/courses/html-css/4/images/grid-col-2.png)

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.

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

![grid with three columns](https://www.ericsdevblog.com/courses/html-css/4/images/grid-col-3.png)

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

![grid with auto columns](https://www.ericsdevblog.com/courses/html-css/4/images/grid-col-auto.png)

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

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  grid-template-rows: 100px 150px;
}
```

![grid with different row heights](https://www.ericsdevblog.com/courses/html-css/4/images/grid-row.png)

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:

```text
grid-template: <row> <row> ... / <col> <col> ...;
```

```css
.container {
  display: grid;
  grid-template: 100px 150px / auto auto auto;
}
```

![grid template](https://www.ericsdevblog.com/courses/html-css/4/images/grid-template.png)

### 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:

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  row-gap: 10px;
  column-gap: 20px;
}
```

![gaps](https://www.ericsdevblog.com/courses/html-css/4/images/gap.png)

Alternatively, you may use the shorthand property, `gap`:

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px 20px;
}
```

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

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
}
```

![gaps with equal spacing](https://www.ericsdevblog.com/courses/html-css/4/images/gap-equal.png)

### 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`).

```html
<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>
```

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
}

.item {
  . . .
}

.item-2col {
  grid-column-start: 1;
  grid-column-end: 3;
}
```

![grid item two columns](https://www.ericsdevblog.com/courses/html-css/4/images/grid-item-2col.png)

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

![column lines and row lines](https://www.ericsdevblog.com/courses/html-css/4/images/col-line-row-line.png)

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:

```css
.item-2col {
  grid-column: 1 / 3;
}
```

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.

```css
.item-2row {
  grid-row-start: 1;
  grid-row-end: 3;
}
```

```css
.item-2row {
  grid-row: 1 / 3;
}
```

![grid row](https://www.ericsdevblog.com/courses/html-css/4/images/grid-row-span.png)

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:

```text
grid-area: <row_start> / <col_start> / <row_end> / <col_end>
```

```css
.item-area {
  grid-area: 1 / 1 / 3 / 3;
}
```

![grid area](https://www.ericsdevblog.com/courses/html-css/4/images/grid-area.png)

## 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:

```html
<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>
```

```css
.container {
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 10px;
  height: 300px;
}
```

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

- `start`

  ```css
  .container {
    align-content: start;
  }
  ```

  ![align content start](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-start.png)

- `end`

  ```css
  .container {
    align-content: end;
  }
  ```

  ![align content end](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-end.png)

- `center`

  ```css
  .container {
    align-content: center;
  }
  ```

  ![align content center](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-center.png)

- `space-between`

  ```css
  .container {
    align-content: space-between;
  }
  ```

  ![align content space between](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-between.png)

- `space-around`

  ```css
  .container {
    align-content: space-around;
  }
  ```

  ![align content space around](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-around.png)

- `space-evenly`

  ```css
  .container {
    align-content: space-evenly;
  }
  ```

  ![align content space evenly](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-evenly.png)

- `stretch`

  ```css
  .container {
    align-content: stretch;
  }
  ```

  ![align content stretch](https://www.ericsdevblog.com/courses/html-css/4/images/align-content-stretch.png)

`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`

  ```css
  .container {
    align-items: start;
  }
  ```

  ![align items start](https://www.ericsdevblog.com/courses/html-css/4/images/align-items-start.png)

- `end`

  ```css
  .container {
    align-items: end;
  }
  ```

  ![align items end](https://www.ericsdevblog.com/courses/html-css/4/images/align-items-end.png)

- `center`

  ```css
  .container {
    align-items: center;
  }
  ```

  ![align items center](https://www.ericsdevblog.com/courses/html-css/4/images/align-items-center.png)

- `stretch`

  ```css
  .container {
    align-items: stretch;
  }
  ```

  ![align items stretch](https://www.ericsdevblog.com/courses/html-css/4/images/align-items-stretch.png)

- `baseline`

  ```css
  .container {
    align-items: baseline;
  }
  ```

  ![align items baseline](https://www.ericsdevblog.com/courses/html-css/4/images/align-items-baseline.png)

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`.

```css
.container {
  align-items: start;
}

.item-sm {
  align-self: end;
}
```

![align self](https://www.ericsdevblog.com/courses/html-css/4/images/align-self.png)

### 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`

  ```css
  .container {
    justify-content: start;
  }
  ```

  ![justify content start](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-start.png)

- `end`

  ```css
  .container {
    justify-content: end;
  }
  ```

  ![justify content end](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-end.png)

- `center`

  ```css
  .container {
    justify-content: center;
  }
  ```

  ![justify content center](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-center.png)

- `space-between`

  ```css
  .container {
    justify-content: space-between;
  }
  ```

  ![justify content between](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-between.png)

- `space-around`

  ```css
  .container {
    justify-content: space-around;
  }
  ```

  ![justify content around](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-around.png)

- `space-evenly`

  ```css
  .container {
    justify-content: space-evenly;
  }
  ```

  ![justify content evenly](https://www.ericsdevblog.com/courses/html-css/4/images/justify-content-evenly.png)

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

- `start`

  ```css
  .container {
    justify-items: start;
  }
  ```

  ![justify items start](https://www.ericsdevblog.com/courses/html-css/4/images/justify-items-start.png)

- `end`

  ```css
  .container {
    justify-items: end;
  }
  ```

  ![justify items end](https://www.ericsdevblog.com/courses/html-css/4/images/justify-items-end.png)

- `center`

  ```css
  .container {
    justify-items: center;
  }
  ```

  ![justify items center](https://www.ericsdevblog.com/courses/html-css/4/images/justify-items-center.png)

- `stretch`

  ```css
  .container {
    justify-items: stretch;
  }
  ```

  ![justify items stretch](https://www.ericsdevblog.com/courses/html-css/4/images/justify-items-stretch.png)

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

```css
.container {
  justify-items: start;
}

.item-sm {
  justify-self: end;
}
```

![justify self](https://www.ericsdevblog.com/courses/html-css/4/images/justify-self.png)

## 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.

```html
<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>
```

```css
.container {
  display: flex;
  gap: 10px;
}
```

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`

  ```css
  .container {
    flex-direction: column;
  }
  ```

  ![flex direction column](https://www.ericsdevblog.com/courses/html-css/4/images/flex-direction-col.png)

- `column-reverse`

  ```css
  .container {
    flex-direction: column-reverse;
  }
  ```

  ![flex direction column reverse](https://www.ericsdevblog.com/courses/html-css/4/images/flex-direction-col-reverse.png)

- `row`

  ```css
  .container {
    flex-direction: row;
  }
  ```

  ![flex direction row](https://www.ericsdevblog.com/courses/html-css/4/images/flex-direction-row.png)

- `row-reverse`

  ```css
  .container {
    flex-direction: row-reverse;
  }
  ```

  ![flex direction row reverse](https://www.ericsdevblog.com/courses/html-css/4/images/flex-direction-row-reverse.png)

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

- `wrap`

  ```css
  .container {
    flex-wrap: wrap;
  }
  ```

  ![flex wrap](https://www.ericsdevblog.com/courses/html-css/4/images/flex-wrap-wrap.png)

- `nowrap`

  ```css
  .container {
    flex-wrap: nowrap;
  }
  ```

  ![flex nowrap](https://www.ericsdevblog.com/courses/html-css/4/images/flex-wrap-nowrap.png)

- `wrap-reverse`

  ```css
  .container {
    flex-wrap: wrap-reverse;
  }
  ```

  ![flex wrap reverse](https://www.ericsdevblog.com/courses/html-css/4/images/flex-wrap-wrap-reverse.png)

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

```css
.container {
  flex-flow: column wrap;
}
```

![flex flow](https://www.ericsdevblog.com/courses/html-css/4/images/flex-flow.png)

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

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

  align-content: center;
  justify-content: center;
}
```

![flex alignment](https://www.ericsdevblog.com/courses/html-css/4/images/flex-align.png)

## 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](https://www.ericsdevblog.com/courses/html-css/5/).

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

- [How to Create Transitions and Animations Using CSS](https://levelup.gitconnected.com/how-to-create-transitions-and-animations-using-css-f5fff20dcaa2)
- [How to Position and Align Elements Using CSS](https://levelup.gitconnected.com/how-to-position-and-align-elements-using-css-73db2ef3d6ac)
- [Working with Typography in CSS](https://blog.devgenius.io/working-with-typography-in-css-ca700859fe27)
- [Three Ways of Defining Colors in CSS](https://medium.com/devdive/three-ways-of-defining-colors-in-css-7b2f98a3fbf3)
- [HTML & CSS: A Practical Guide](https://www.ericsdevblog.com/courses/html-css/)