DEV Community

Cover image for Creating A Quick Grid System With Flexbox
Roland Taylor
Roland Taylor

Posted on

Creating A Quick Grid System With Flexbox

Greetings, Earth-things!

Today, I'm going to show you how to create a flexible grid system using Flexbox! Flexbox is pretty well-supported across pretty much all the browsers (except for some quirks in IE11, offfff course), so this should work even where display: grid does not!

As a bonus, this demo will allow you to add or remove cells from the grid with a click!

First, let's set up our environment

I'm using two fonts from Google's Font Library, Open Sans and Dosis. Let's set up their import statement first:

Code:

@import url('https://fonts.googleapis.com/css2?family=Dosis:wght@200&family=Open+Sans&display=swap');
Enter fullscreen mode Exit fullscreen mode

We'll be using two custom properties later, so let's set them up at the top of our CSS code, just below the import above:

Code:

:root {
  --border: rgba(255, 255, 255, .2);
  --page-color: rgb(235, 235, 235);
}
Enter fullscreen mode Exit fullscreen mode

As always, I like to do things with a little style. For the background, I'm going to use a nice gradient, and disable padding and margins on the body.

Code:

body {
  background-image: linear-gradient(rgb(135, 35, 135), rgb(75, 135, 195), rgb(35, 48, 135));
  background-attachment: fixed;
  background-size: cover;
  color: var(--page-color);
  font-family: 'Open Sans', sans-serif;
  font-size: 18px;
  letter-spacing: .135ch;
  margin: 0;
  padding: 0;
}
Enter fullscreen mode Exit fullscreen mode

Next, let's include a little description of what we're building (Optional)

We'll need a heading (h1) and a section:

Code:

<h1>
   flexi-grid demo
</h1>
<section class="description">
   Hi! This is a little demo of a
   simple grid system usingFlexbox!
   You can add a new box to the
   grid by clicking on the "+", or
   remove a cell by clicking on the "-".
</section>
Enter fullscreen mode Exit fullscreen mode

And then we'll style them:

Code:

h1 {
  color: white;
  display: flex;
  font-family: 'Dosis', sans-serif;
  font-variant: small-caps;
  justify-content: center;
  letter-spacing: .235ch;
  margin: 5vw 0 2.5vw 0;
}

.description {
  align-items: center;
  background: rgba(85, 85, 85, .2);
  border-radius: 8px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, .3);
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  line-height: 4ch;
  padding: 3.5vw 7.365vw;
  margin: 0 15vw 5vw 15vw;
  text-align: center;
}
Enter fullscreen mode Exit fullscreen mode

You should end up with something like this:
A screenshot showing the heading and description

Now, let's build the container

The container itself is invisible, but it's one of the most critical components of our grid system. It holds the cells and tells them how they should be laid out.

Fortunately, it's pretty easy to set up. First, let's add a main element to our HTML:

Code:

<main class="flexi-grid" id="grid">

</main>
Enter fullscreen mode Exit fullscreen mode

You'll notice that I've included a class, .flexi-grid and give this element an ID, grid. These attributes will be critical to the rest of this tutorial, so make sure to include them.

  • The class flexi-grid will be used to define our grid system.
  • The id grid, will be used to target this element via JavaScript.

Let's go ahead and set up the CSS for our grid container:

Code:

.flexi-grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  padding: 0 .5vw;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Some things of note:

  • Within this declaration block, we've set the display property to flex; which tells the browser to use the Flexbox system for this element.
  • Next we've set the flex-flow property to row wrap. This covers two properties in one go: flex-direction, and flex-wrap. Later on, we will change this property to column, for smaller screens.
  • Setting the property justify-content: to flex-start; tells the browser to align our grid cells toward the beginning (left side) of the row.
  • I've padded the container to align its contents to the centre. By using the appropriate value in view-width (vw) units, we can have this done automatically.

Creating the grid cells

With our container in place, we need to actually add some cells to the grid to make it... you know... a grid. To achieve this, we'll create a new class, flexi-cell-25*.


* We can add grid cells of other sizes, but for convenience, and the purposes of this tutorial, we're sticking with quarters.


Code:

.flexi-cell-25 {
  border: 1px solid var(--border);
  box-sizing: border-box;
  margin: .5vw .5vw;
  height: 23.5vw;
  width: 23.5vw;
  box-shadow: 0 3px 12px rgba(0, 0, 0, .3);
}
Enter fullscreen mode Exit fullscreen mode

Some things of note:

  • We're using the custom property we defined earlier, --border.
  • box-sizing: border-box; ensures that our grid cells are not affected in terms of overall size, by either their borders or their padding (should we choose to add it).
  • For the margin, I'm using the same value as the padding used by the container. This maintains (proportionally) even spacing regardless of screen dimensions.
  • height: and width: are not set exactly to 25vw. This is on purpose. For the purposes of this tutorial, I actually want spacing between each cell, but still want each cell to take 1/4th of the screen width, and the same height. If you want to give each cell the same width, but adjustable height, you could replace height: with align-self: stretch;.

To see how these grid cells look, add the following to main:

<div class="flexi-cell-25">

</div>
<div class="flexi-cell-25">

</div>
Enter fullscreen mode Exit fullscreen mode

At this point, we should have a page that looks like this:

A screenshot of the demo up to this point


Bonus: Add and remove buttons

We've technically completed our grid system, but we're going to extend it a bit by adding add/remove buttons.

Our HTML Code:

Within main, we'll put the following, adjusting what we had before:

<div class="flexi-cell-25 flexi-grid-new" onclick="newCell()">

</div>
<div class="flexi-cell-25 flexi-grid-remove" onclick="removeCell()">

</div>
Enter fullscreen mode Exit fullscreen mode

Our embedded JavaScript Code:

At the bottom of the file, we'll add this script:

<script type="text/javascript">
   var grid = document.getElementById("grid")

   function newCell() {
      let cell = document.createElement("div")
      cell.classList.add("flexi-cell-25")
      grid.appendChild(cell)
   }

   function removeCell() {
      grid.removeChild(grid.lastElementChild)
   }
</script>
Enter fullscreen mode Exit fullscreen mode

Some things to note:

  • We're pulling from the id of the grid container, because using querySelector() stops us from being able to use appendChild() (it apparently returns a string and causes an error).
  • Placing cell outside newCell() (as a global variable) does not work. Ensure it's within the function.
  • You can make newCell() more versatile by passing the class to add to new cells as an argument. You can try this on your own.

Finally, let's style our add/remove buttons:

.flexi-grid-new, .flexi-grid-remove {
  border-style: dashed;
  position: relative;
}

.flexi-grid-new::after {
  content: '+';
}

.flexi-grid-remove::after {
  content: '-';
}

.flexi-grid-new::after,
.flexi-grid-remove::after {
  align-items: center;
  bottom: 0;
  display: flex;
  font-size: 5ch;
  justify-content: center;
  left: 0;
  opacity: .35;
  position: absolute;
  right: 0;
  top: 0;
  transition-duration: .735s;
}

.flexi-grid-new:hover::after,
.flexi-grid-remove:hover::after {
  opacity: 1;
  transform: scale(1.35);
}
Enter fullscreen mode Exit fullscreen mode

Some things to note:

  • I've combined definitions wherever possible, to avoid duplication.
  • Rather than wrangling with the position of the text, I've simply let the overlays (::after pseudo-elements) take up the full space of their parent elements, and used Flexbox properties to position them in the centre.

That's it!

That's about all there is to it! You can play around with this tutorial and see what you can come up with. If you do, feel free to share your creations with me!

You can view the source code here: https://codepen.io/rolandixor/pen/rNwEgPb

Top comments (0)