CSS Flex and grid

CSS3 brings two useful methods for creating designs that work on varying resolutions of screen.

Flex

Flex allows you to define how elements will be arranged inside a container. Do you want them stacked in a column, or going horizontally. Do they gather to the left, right or spaced evenly.

As the size of the container changes, the sub items will rearrange to fit.

Grid

Grid allows you to split an area up into rows and columns. This is useful for making the layout of a page or a section of it.


Flex

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Flex Test</title>
  <style>
    .flexbox-container {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
    }
    .flexbox-container div {
      background-color: #8888ff;
      border: 1px solid black;
      margin: 5px;
      font-size: 4rem;
      width: 15em;
      height: 5em;
    }
  </style>
</head>
<body>
  <div class="flexbox-container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
</body>
</html>

Try changing the direction and wrap rules to see how the display changes.

There are further options. For example, flex-direction can also use row-reverse and column-reverse for values. Flex-wrap can be set to wrap-reverse if you wanted the extra items to wrap to lines above the original.

Here we define a div to be the container by using the display: flex property. We use flex-direction: row to tell the browser to show the sub items of the contain in a horizontal row. We could have used flex-direction: column if you wanted them stacked vertically on top of each other. We use flex-wrap: wrap to say “When you can’t fit all the elements on one line, wrap them onto another one”. If you wanted to force them onto a line you could use flex-wrap: nowrap.

You can ignore all the properties on the the child items as that’s just to make them more visible for the demonstration.

Flex items on a wide display
Flex items on a wide display

If we look at the same code on a display that can only fit one of the child items into the contain on a row they automatically stack.

Flex items on a narrow display
Flex items on a narrow display

If you want to use a percentage of the flex container you could use the flex-basis property on the child elements. So 2 equal columns could use:

.flexbox-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.flexbox-container > div {
  flex-basis: 50%;
}

Each child div would take up 50% of the width of the parent.


Justify-content

justify-content aligns the items within the container. By default it puts all the items to the left, unless you are using a flex-direction of row-reverse. But it can have the values:

flex-start

Example of justify-content: flex-start
Example of justify-content: flex-start

All the child elements are aligned to the left side of the container, or right on row-reverse.

flex-end

Example of justify-content: flex-end
Example of justify-content: flex-end

All the child elements are aligned to the right side of the container, or left for row-reverse.

center

Example of justify-content: center
Example of justify-content: center

All the child elements are aligned in the center of the container.

space-around

Example of justify-content: space-around
Example of justify-content: space-around

The container works out how many will fit on a row and then divides the width available between the child elements then centre aligns each element in its own section.

space-between

Example of justify-content: space-between
Example of justify-content: space-between

The container works out how many will fit on a row and then puts one to the far left, one to the far right, and the rest are equally spaced between.

Add a justify-content property to your container. Choose whichever value you want.


Align-content

This property controls how the child items are vertically aligned within the container if the container is taller than the items. By default it puts all the items to the top. It can have the values:

flex-start

An example of align-content: flex-start
An example of align-content: flex-start

flex-end

An example of align-content: flex-end
An example of align-content: flex-end

center

An example of align-content: center
An example of align-content: center

space-around

An example of align-content: space-around
An example of align-content: space-around

space-between

An example of align-content: space-between
An example of align-content: space-between

stretch

An example of align-content: stretch
An example of align-content: stretch

Stretch will only be apparent if you haven’t set a height property for the child elements.


Grid

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Grid Test</title>
  <style>

    body {
      margin: 0;
    }
    .grid-container {	
      display: grid;
      grid-template-columns: auto auto auto;
    }
    .grid-item {
      background-color: #8888ff;
      border: 1px solid black;
      margin: 2px;
      height: 5em;
    }
  </style>
</head>
<body>
<div class="grid-container">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
</div>
</body>
</html>

Here we define a div to be our grid container using display: grid, we then use the grid-template-columns: auto auto auto to set the grid to have 3 equally sized colums.

Example of grid with 3 even columns
Example of grid with 3 even columns

Maybe we want to use this grid for a layout and have a large centre area and different sizes on each side. Instead of using auto auto auto we can set sizes

grid-template-columns: 25vw 70vw 5vw;
Example of grid with 3 uneven columns
Example of grid with 3 uneven columns

A really useful new size unit for grids is fr which stands for fraction of the available space.

grid-template-columns: 1fr 2fr;

In the above the 2nd column will be twice the width of the 1st column. And fr ignores any space set aside for gaps between columns.

How to change the number of columns? Change the number of values in the grid-template-column property. So 5 equal columns would be:

grid-template-columns: auto auto auto auto auto;

If you want to control the rows rather than columns then it follows the same pattern. Just use the grid-template-rows property instead.

grid-template-rows: 200px 100px 50px;
Example of grid-template-rows
Example of grid-template-rows

Justify-content

If the items don’t take up the full width of the container then you can use the justify-content property to change how they are arranged:

space-evenly

Example of justify-content: space-evenly
Example of justify-content: space-evenly

space-around

Example of justify-content: space-around
Example of justify-content: space-around

space-between

Example of justify-content: space-between
Example of justify-content: space-between

flex-start

Example of justify-content: flex-start
Example of justify-content: flex-start

center

Example of justify-content: center
Example of justify-content: center

flex-end

Example of justify-content: flex-end
Example of justify-content: flex-end

Align-content

If the items don’t take up the full height of the container then you can use the align-content property to change how they are vertically arranged:

space-evenly

Example of align-content: space-evenly
Example of align-content: space-evenly

space-around

Example of align-content: space-around
Example of align-content: space-around

space-between

Example of align-content: space-between
Example of align-content: space-between

flex-start

Example of align-content: flex-start
Example of align-content: flex-start

center

Example of align-content: center
Example of align-content: center

flex-end

Example of align-content: flex-end
Example of align-content: flex-end

Gaps

What if your grid items take up the full size but you still want a space between each. Use a gap property.

  • column-gap
  • row-gap
  • gap (this is just shorthand for row-gap and column-gap together)

For example the image to the right has a column-gap of 40px and a row-gap of 10px. This could be done as:

gap: 10px 40px;

Or as:

column-gap: 40px;
row-gap: 10px;
Example of gaps
Example of gaps

Grid items

Up until now all your styles have been applied to the container. But the items have options too:

  • grid-column-start
  • grid-column-end
  • grid-column (shorthand for “grid-column-start / grid-column-end”)
  • grid-row-start
  • grid-row-end
  • grid-row (shorthand for “grid-row-start / grid-row-end”)
  • grid-area (shorthand for “grid-row-start / grid-column-start / grid-row-end / grid-column-end”)

The grid-column property allows you to define the start and end columns of a child item within a grid.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Test</title>
  <style>
    .grid-container {
      grid-template-columns: auto auto auto auto auto auto;
      grid-template-rows: auto auto;
      display: grid;
      height: 600px;
      width: 600px;
      border: 1px solid black;
    }
    .grid-item {
      background-color: #8888ff;
      border: 1px solid green;
      margin: 2px;
    }
  </style>
</head>
<body>
  <div class="grid-container">
    <div class="grid-item" style="grid-column: 1 / 4">1</div>
    <div class="grid-item" >2</div>
    <div class="grid-item" style="grid-column: 5 / 7">3</div>
    <div class="grid-item">4</div>
    <div class="grid-item" style="grid-column: 2 / 6">5</div>
    <div class="grid-item">6</div>
  </div>
</body>
</html>
Example of grid-columns
Example of grid-columns

Here we have a grid made up of 2 rows and 6 columns. The first child item has a property of grid-column: 1 / 4 which means “start at column 1 and end at column 4” in other words, start in the first column and span 3 columns. You can even write it that way.

grid-column: 1 / span 3;

The grid-row property works exactly the same. State in which row the item should and then say either where it ends or how many it spans.

The grid-area property combines grid-row and grid-column.

grid-area: 1 / 2 / 3 / 4;

grid-row-start is set to the first value, grid-column-start is set to the second value, grid-row-end is set to the third value, and grid-column-end is set to the fourth value. So this would be the same as:

grid-row: 1 / 3;
grid-column: 2 / 4;
Report a Glow concern
Cookie policy  Privacy policy

Glow Blogs uses cookies to enhance your experience on our service. By using this service or closing this message you consent to our use of those cookies. Please read our Cookie Policy.