Grid vs. Flexbox: An Introduction to the Useless Battle

Through time has been common to compare things that can do similar functions, for the sake of electing a champion, something that is better, be it reason “y” or reason “x”, and specially to be on the “right” side.
If you think that you haven’t done something like that maybe these topics will remind you of something, “XBOX or PlayStation?”, “Android or iOS?”, “Java or .Net?” and the list can go on, sometimes making a fuss about which one is better is pointless.

As I started to learn more and more about Web Developments i came across two wonderful properties Flexbox and Grid, these two are used to create awesome designs, when I first learned about them I instinctively felt more liking to Flexbox and to be honest for a short period of time i thought that was better that Grid, some other members of my team at Microverse liked more Grid, we were wrong trying to get one of the two as the best.
Note: this article is for Junior web developers, there is not going to be a lot of explanation for the Flexbox or Grid properties used, for a more “tutorial” minded article I would recommend this one for Flexbox and this one for Grid

Flexbox

Flexbox is a one-dimensional layout system, content-based, it helps us to distribute the space between the elements even with setting how much an element will grow or shrink in comparison to the other elements in the same container, one of the best options to add responsiveness at your web page.

Grid

Grid is a two-dimensional layout system, it is more complex than Flexbox in certain ways, it can be really helpful to create complex layouts, with Grid we need to define how much columns and rows will it have.

What can they do?

Both of them are layout systems, technically we can do the same with both of them, but, in some cases Grid or Flexbox will be easier to use

Create a layout

For the first comparison we will do the next layout with Grid and flexbox

  • One bar with 100% height at left
  • One bar at the top-right corner with 50% height and 75% width
  • Two boxes at the bottom-right cornet with 50% height and 32.5% of width each one

Flexbox

With Flexbox is not impossible to create a layout, but, we need to take into account that we can only distribute the space for each element in one direction per container (column or row).

HTML for Flexbox

<div class="container">
  <div class="left-bar"></div>
  <div class="main-content">
    <div class="main-content-top"></div>
    <div class="main-content-bottom">
      <div class="main-content-bottom-left"></div>
      <div class="main-content-bottom-right"></div>
    </div>
  </div>
</div>

Now we will apply the styling

container class

.container {
  width: 100%;
  height: 300px;
  display: flex;
}
  • display: flex .- With this, we make every direct child a flex item, we will distribute the space between the “left-bar” and the “main-content” classes

left-bar class

.left-bar {
  flex: 1;
  background-color: green;
}
  • flex: 1 .- With this we make the element receive the specified proportion of free space, it will be taken as 1/n, “n” is based in the total sum of all the specified proportions in al the child elements of the class

main-content class:

.main-content {
  flex: 3;
  display: flex;
  flex-direction: column;
}
  • flex: 3 .- since we are already taking 1 portion with “left-bar” means that with this set proportion we will be receiving 3/4 of the free space.
  • display: flex .- now we make every direct child of the container flex items, with this we will distribute the space between the bar at the top and the two elements at the bottom.
  • flex-direction: column .- the elements will be arranged vertically and the free space will be distributed in the same direction

main-content-top class

.main-content-top {
  flex:1;
  background-color: blue;
}
  • flex: 1 .- We take 1 proportion of the container free space

main-content-bottom class

.main-content-bottom {
  flex:1;
  display: flex;
}
  • flex: 1 .- we take 1 proportion of the free space
  • display: flex .- we make the child a flex element, to distribute the space between the two elements at bottom

main-content-bottom-left class

.main-content-bottom-left {
  flex: 1;
  background-color: red;
}
  • flex: 1 .- We set proportion of free space that is going to take

main-content-bottom-right class

.main-content-bottom-right {
  flex: 1;
  background-color: orange;
}
  • flex: 1 .- We set proportion of free space that is going to take

Grid

With grid is easier to create layouts, we can divide the container in cells and assign how much row and column cells will it take

HTML for Grid

<div class="container">
  <div class="left-bar">
  </div>
  <div class="main-content-top">
  </div>
  <div class="main-content-bottom-left">
  </div>
  <div class="main-content-bottom-right">
  </div>
</div>

CSS with Grid

container class

  • display: grid .- We make the container a grid container
  • grid-template-columns .- with this we set how much columns is going to have the container, in this case, “repeat” creates 6 columns of 1 fraction of the width of the container
  • grid-template-rows .- This property creates a number of rows in the container, in this case we create 4 rows of 1 fraction

left-bar class

.left-bar {
  grid-column: span 2;
  grid-row: span 4;
  background-color: red;
}
  • grid-column: span 2 .- we make the container to span 2 spaces of the total columns
  • gird-row: span 4 .- we make the container to span 4 spaces of the total rows

main-content-top class

.main-content-top {
  grid-column-start: 3;
  grid-column: span 4;
  grid-row: span 2;
  background-color: green;
}
  • grid-column: span 4 .- we make the container to span 4 spaces of the total columns
  • gird-row: span 2 .- we make the container to span 4 spaces of the total rows

main-content-bottom-left class

.main-content-bottom-left {
  grid-column-start: 3;
  grid-row-start: 2;
  grid-column: span 2;
  grid-row: span 2;
  background-color: blue;
}
  • grid-column: span 2 .- we make the container to span 2 spaces of the total columns
  • grid-row: span 2 .- we make the container to span 2 spaces of the total rows

“main-content-bottom-right” class

.main-content-bottom-right {
  grid-column-start: 5;
  grid-row-start: 2;
  grid-column: span 2;
  grid-row: span 2;
  background-color: orange;
}
  • grid-column: span 2 .- we make the container to span 2 spaces of the total columns
  • grid-row: span 2 .- we make the container to span 2 spaces of the total rows

With Grid we don’t have to make as much groups of containers as we may have to make with Flexbox, also it makes easier to move around the containers in certain breakpoints allowing us to change height and width of any element while maintaining the distribution of space of all the other elements. in this type of scenarios personally i think that it’s better grid.

Align elements within a container

One of the most tedious and common thing to do personaly, is aligning elements, and even more when the number of elements that is shown is based on Account permissions,

For this test we will use the same HTML file

<div class="container">
  <div class="left-bar">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
    <p>Something at middle</p>
    <p>Something at bottom</p>
  </div>
  <div class="main-content-top">
    <p>element 1</p>
    <p>element 2</p>
    <p>elementelementelement 3</p>
    <p>element 4</p>
  </div>
  <div class="main-content-bottom-left">
  </div>
  <div class="main-content-bottom-right">
  </div>
</div>

We will use basically the same CSS for Flexbox and Grid, with some changes that will be added below

.container {
  width: 100%;
  height: 300px;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(4, 1fr);
}

.left-bar {
  grid-column: span 2;
  grid-row: span 4;
  background-color: red;
  justify-content: space-between;
  color: white;
}

.main-content-top {
  grid-column-start: 3;
  grid-column: span 4;
  grid-row: span 2;
  background-color: green;
  justify-content: space-between;
  align-items: center;
  color: white;
}

.main-content-bottom-left {
  grid-column-start: 3;
  grid-row-start: 2;
  grid-column: span 2;
  grid-row: span 2;
  background-color: blue;
}

.main-content-bottom-right {
  grid-column-start: 5;
  grid-row-start: 2;
  grid-column: span 2;
  grid-row: span 2;
  background-color: orange;
}

Flexbox

Aligning elements within containers it’s easy with flexbox but we have to keep in mind that we can only distribute the space in one direction at the time

HTML

In the HTML we will only add the class “flex-1” and “flex-2” to the p elements inside the “main-content-top” container.

<div class="main-content-top">
  <p class="flex-1">element 1</p>
  <p class="flex-1">element 2</p>
  <p class="flex-2">elementelementelement 3</p>
  <p class="flex-1">element 4</p>
</div>

CSS

left-bar class

.left-bar {
  grid-column: span 2;
  grid-row: span 4;
  background-color: red;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: white;
}
  • display: flex .- we make the container a flex container
  • justify-content: space-between .- the elements distribute the space so they can separate equally through all the container
  • flex-direction: column .- set the direction in which the elements will be aligned to vertical

main-content-top class

.main-content-top {
  grid-column-start: 3;
  grid-column: span 4;
  grid-row: span 2;
  background-color: green;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  color: white;
}
  • display: flex .- Makes container a flex container
  • flex-wrap: wrap .- If there is not enough space for the elements, those will be moved to a line below

flex-“n” classes

.flex-1 {
  flex: 1;
}

.flex-2 {
  flex: 2;
}
  • These two classes are created to be able to assign more space in case the element is too big, this is perfect when we need to handle dynamic added elements

Grid

We already saw how helpful it is to have the possibility of adding columns and rows of any given width or height we want, but, how will this works with aligning elements?

HTML

The HTML will remain as it was presented at top

CSS

left-bar class

.left-bar {
  grid-column: span 2;
  grid-row: span 4;
  background-color: red;
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  color: white;
}
  • display: grid .- We start by making our container a greed container
  • grid-template-rows: repeat(3, 1fr) .- We set the columns as 1fr and not with auto so each element has the same height

main-content-top class

.main-content-top {
  grid-column: span 6;
  grid-row: span 2;
  background-color: green;
  display: grid;
  grid-template-columns: 1fr 1fr 2fr 1fr;
  align-items: center;
}
  • display: grid .- Make container a grid container
  • grid-template-columns: 1fr 1fr 2fr 1fr .- We cant create four columns of the same height because one of the elements is bigger than the other three.

Which one is better?

When it comes to designing layouts it’s way easier to work with Grid, we just have to divide our container with as much columns and rows we want to and set the child elements how much columns and rows do we want them to take, with Flexbox it can be more time consuming and larger HTML files since we have to create multiple containers to distribute space in different axis, in this type of cases without doubt Grid is the winner.

When we have to align elements inside a container it’s way easier with Flexbox, with grid we have to set how much rows or columns will have the container, even if Grid has options as implicit rows, it doesn’t give us the possibility of setting dynamically the space for each column, with Flexbox in the other hand the space will be distributed between all the elements, this helps a lot with dynamic content.

We can accept that there is not a better or easier technology, it depends in what we want to build, Grid works for most of the cases when we need to create layouts and Flexbox for aligning elements. Using both in the right place can help us save a lot of time and maybe the tediousness of having to modify the HTML and CSS in the future if a new feature or element is required to be shown.

read original article here