How to Start to Use Flexbox and CSS Grid in Your Projects

Author profile picture

@andresporrasOscar Russi

During years I've been using Bootstrap, the most popular UI library for responsive web design, both for my job and also for my personal projects, but in the software development world new technologies appear every year, the old ones keep evolving. Besides, the web designer has been facing a problem, to make responsive web design to the request of users for more friendly user interfaces for different devices. For this reason, in recent years CSS bring two novelties, flexbox and CSS Grid. Just two weeks ago I had never used these alternatives.
My purpose here is to introduce the basics concepts that I have used in these first days of not using bootstrap anymore.
So here I am, learning two different ways to make the responsive layouts of the websites.

FLEXBOX

First of all, let's make a simple degree with flexbox to see how to works.
This is our css code
.flex-content {
    display: flex;
    height:100px;
    text-align:center;
    font-size: 48px;
}

.flex-left {
    flex: 1;
    background-color:blue;
}

.flex-center {
    flex: 2;
    background-color:red;
}

.flex-right {
    flex: 3;
    background-color:green;
}
In our HTML we will contain this code:
<main class="flex-content">
        <div class="flex-left">this</div>
        <div class="flex-center">is</div>
        <div class="flex-right">flexbox</div>
    </main>
The aftermath will be this:
In order to use flexbox, we define a "display: flex;" in the main tag. inside this tag we add another three div tags, the first one use the class "flex-left", which contains the property "flex:1;", the second div use the class "flex-center" with the property "flex: 2;" and the last div use the class "flex-right" which contains the property "flex: 3;".
The flex property defines the number of columns to be used, in other words, the flex property defines how many fractions use the current element. In the example we have 6 columns (or 6 fractions) in all the row, as a consequence, the last div uses 50% of the row width because it uses 3 of 6. In the flexbox layout, the size of each element is defined inside the item itself. If we copy the last div and paste it before the first div then the page will look like this:
ONE COLUMN
With the property "flex-direction" we can control the axis an the direction of the items inside the container. By default, the value of "flex-direction" in the flex container is "row" which makes the items to be added from left to right. "flex-direction" has another three possible values:
  • row-reverse: right to left
  • column: top to bottom
  • column-reverse: bottom to top
Let's change the behavior of the items inside the main tag by adding the property "flex-direction: column;" to the flex-container class.
.flex-content {
    display: flex;
    flex-direction:column;
    text-align:center;
    height: 240px;
    width: 480px;
    font-size: 24px;
}

.flex-content > div:nth-child(even) {
    flex: 1;
    background-color:red;
}

.flex-content > div:nth-child(odd) {
    flex: 3;
    background-color:blue;
}
Four columns inside the main tag
<main class="flex-content">
        <div>this</div>
        <div>is a</div>
        <div>flexbox</div>
        <div>column</div>
    </main>
When we use a flex container as a column we will need to define a height to the container, otherwise, it will ignore the property "flex" of each item contained.
BIDIMENSIONAL LAYOUT
For now, we can use flexbox to control one row or one column, but what if want that the content uses multiple rows and columns? unfortunately, flexbox is made by working in just one direction, but we can achieve a two-dimensional behavior by using the
flex-wrap
property. By default, every new element is always placed in the same line (row or column), this is because, by default, the flex layout has the property "flex-wrap: nowrap;". Let's change the default behavior:
.flex-content {
    display: flex;
    flex-wrap: wrap;
    height:200px;
    text-align:center;
    font-size: 48px;
}

.flex-content > div{
    flex-basis: 25%;
}

.flex-content > div:nth-child(3n+0) {
    background-color:green;
}

.flex-content > div:nth-child(3n+1) {
    background-color:blue;
}

.flex-content > div:nth-child(3n+2)  {
    background-color:red;
}
And the HTML code:
<main class="flex-content">
        <div>ITEM 1</div>
        <div>ITEM 2</div>
        <div>ITEM 3</div>
        <div>ITEM 4</div>
        <div>ITEM 5</div>
        <div>ITEM 6</div>
    </main>
Now we have defined that the container is using "
wrap
" property, as a consequence, the content will move to the next row when the previous elements have used the 100% of the width. To define how much width will be used by each child's element we use "
flex-basis
" property for every child.
CSS GRID
While flexbox is a content base layout, Grid is container-based. As a consequence, in Grid the size of each item in the container is defined in the container, different to flexbox where the size was defined on each container. Another important difference is that Grid was naturally made to manage two-dimension layouts, while flexbox works better in one layout. Let's see a basic implementation of a CSS Grid.
.grid-container {
    display: grid;
    grid-template-columns: 2fr 1fr;
    grid-template-rows: 100px 200px;
    font-size: 48px;
    width: 300px;
    height:300px;
    grid-gap:10px;
    color:white;
  }

  .grid-container > div {
    background-color:black;
  }

  .grid-1-1 {
    grid-row: 1;
    grid-column: 1;
  }
  
  .grid-1-2 {
    grid-row: 1;
    grid-column: 2;
  }
  
  .grid-2-1 {
    grid-row: 2;
    grid-column: 1;
  }
  
  .grid-2-2 {
    grid-row: 2;
    grid-column: 2;
  }
four divs inside the tag with the grid layout.
<main class="grid-container">
        <div class="grid-1-1">1</div>
        <div class="grid-1-2">2</div>
        <div class="grid-2-1">3</div>
        <div class="grid-2-2">4</div>
    </main>
First of all, our Grid container should have a "display: grid;" property. We use the property "
grip-template-columns
" to define the number of columns and the size of each column. The "grid-template-columns: 2fr 1fr;" the total of columns and the size of each column. "
fr
" represents "fraction", therefore "
2fr
" means 2 fractions from the total of the dimension. In our example, the row dimension has 3 fractions (2fr + 1fr). We can also use pixels instead of fractions for defining the size of each column, the same for the rows.
With the property "grid-template-rows: 100px 200px;" we defined two rows, the first with a height of 100 pixel, the second with a height of 200px. Also, we defined the property "
grid-gap
" to define a distance between rows and columns. Finally, we created a class for each item, to define the column and row where each item should be placed, we can make this with the properties "
grid-column
" and "
grid-row
".
USING MULTIPLES ROWS AND COLUMNS FOR AN ITEM
In the previous example we use and specific row and a column for each item, we can also use more than one row or column for specific items. In this new example, we are going to use six items in a Grid of 3 rows and 3 columns.
The CSS code:
.grid-container {
    display: grid;
    grid-template-columns: 100px 100px 100px ;
    grid-template-rows: 1fr 1fr 1fr;
    width: 300px;
    height:300px;
    grid-gap:10px;
  }

  .grid-container > div {
    background-color:blue;
    color: red;
    font-size: 24px;
  }

  .first-item{
      grid-row: 1 / span 2;
      grid-column:1;
  }

  .second-item{
    grid-row: 1;
    grid-column:2 / span 3;
}

.third-item{
    grid-row: 2 / span 3;
    grid-column:2 ;
}

.fourth-item{
    grid-row: 2;
    grid-column:3;
}

.fifth-item{
    grid-row: 3;
    grid-column:3;
}

.sixth-item{
    grid-row: 3;
    grid-column:1;
}
And the HTML code:
<main class="grid-container">
        <div class="first-item">1</div>
        <div class="second-item">2</div>
        <div class="third-item">3</div>
        <div class="fourth-item">4</div>
        <div class="fifth-item">5</div>
        <div class="sixth-item">6</div>
    </main>
Each row and column will have the same size. For the first item, we use the property "
grid-row: 1 / span 2;
", which means that these elements will be placed in both the first and the second row. For the second item, we use "
grid-column:2 / span 3;
" in order to use both the second and the third column.
CONCLUSION
CSS Grid provides a level of flexibility for two dimensions which is not available in flexbox, but at the same time, flexbox allows each content element to define its size, which makes it easier to define a responsive design when we are working on a specific row or column. As a conclusion, Grid seems to be a better option for defining the general layout of the pages, while flexbox can be more flexible to be used on specific sections of the pages, like a navbar, an aside element or a footer.
Compare with bootstrap 3 (which layout methodology is mostly built around float property) both methodologies provide greater flexibility and responsiveness. This was just a first checking of the basic concepts for these two layout systems, all in all, I can conclude that each alternative has its own strengths and weaknesses, the most important is to have the knowledge of each alternative in order to choose the most adequate for every problem.

Tags

The Noonification banner

Subscribe to get your daily round-up of top tech stories!