Tania Rascia Web Design and Development

Skip Navigation
How to Create a Flexbox Grid

How to Create a Flexbox Grid

/ 17 responses

The Flexbox layout module is good news for web developers everywhere. The part where all major browsers now support it is even better news. A lot of fantastic resources, documentation and tutorials have sprung up lately. Solved by Flexbox is one of my favorites.

In the past I used very simple CSS float grids for website templating, but Flexbox is even better, and much simpler. In this quick tutorial, I will show you how to create an extremely simple, infinitely scalable responsive grid.

The Demo

See the Pen Easiest Flex Grid Ever by Tania (@taniarascia) on CodePen.

We have semantic options for naming the tags and classes, but I’ll start off with a simple row and column based naming structure, in the vein of Bootstrap, Foundation, Skeleton, and just about every other CSS framework.

Note that I’m only writing about the functional code. For the examples, I’ve added borders and background colors to the grid to make it easier to understand.

The CSS

With only two classes – .row and .column – we can create an infinite, equally spaced grid.

.row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.column {
  flex-basis: 100%;
}

@media screen and (min-width: 800px) {
  .column {
    flex: 1;
  }
}

A Guide to Flexbox by Chris Coyier explains Flexbox in detail. For this grid, we only use a few flex properties.

  • display: flex defines a flex container.
  • flex-direction: row determines the direction of each child in a flex container as left-to-right.
  • flex-wrap: wrap will allow a multi-line flex.
  • flex-basis: 100% specifies the initial main size of a flex item (100%).

I have my mobile breakpoint set to 800px. This grid can become more complicated and have more breakpoints, but I like to have just one for mobile/tablet (small screens) and one for desktop/laptop (large screens). Using min-width media queries is optimal for mobile first layout design.

The way this is set up, each column will have 100% width on mobile, and wrap down to the next column. On desktop, all the colums will be contained to a single line.

The HTML

In a framework like Bootstrap, the grid is based on 12 columns. A 50% width column would be written something like col-md-6. This is much simpler.

First, create a row.

<div class="row">
</div>

Inside that row, insert a column.

<div class="row">
  <div class="column">
  <!-- 100% width -->
  </div>
</div>

This will give you one 100% wide column. Add another column.

<div class="row">
  <div class="column">
  <!-- 50% width -->
  </div>
  <div class="column">
  <!-- 50% width -->
  </div>
</div>

The width of each column is 100% divided by the number of columns within the flex container (.row). Predictably, adding another with divide once again.

<div class="row">
  <div class="column">
  <!-- 33.33% width -->
  </div>
  <div class="column">
  <!-- 33.33% width -->
  </div>
  <div class="column">
  <!-- 33.33% width -->
  </div>
</div>

So far, we have equally dividing columns.

Large Screen View

Small Screen View

Also, the grid is infinitely nestable.

But that’s only so useful. What if you want a Holy Grail layout? Or a main content with a sidebar?

Well, on the small screen view, it’s still going to look the same – you still want each section to be full width. On desktop, it will be slightly different. Going with the Holy Grail example, say I want a main left sidebar that’s 25% width, an advertisement sidebar on the right that’s 20% width, and the 55% as the main content?

The class names can be anything, but I’m just going to name them after the percents for simplicity.

<div class="row">
  <div class="column _25">
    25% Left Sidebar
  </div>
  <div class="column _55">
    55% Main Content
  </div>
  <div class="column _20">
    20% Right Sidebar
  </div>
</div>

The only thing that needs to be added is the flex property inside of your min-width media query.

@media screen and (min-width: 800px) {
  ._25 {
    flex: 2.5;
  }
  ._55 {
    flex: 5.5;
  }
  ._20 {
    flex: 2;
  }
}

Large Screen View

Small Screen View

Finally, you’re going to want to wrap the entire grid inside of a container so your content doesn’t stretch to 3000 pixels wide on an iMac.

<div class="container">
  <!-- rows and columns -->
</div>
.container {
  max-width: 1200px;
  margin: 0 auto;
}

Semantics

Everybody loves HTML5 semantics. Why stick with divs upon divs when we have some semantically named classes we can use instead? Rows and columns are great for quick template design, but once it comes down to the final code, you want something cleaner. Read all about HTML5 semantic tags if you’re not overly familiar.

HTML
<main>
  <section>
    <article>
      Article
    </article>
    <aside>
      Aside
    </aside>
  </section>
</main>

main is the .container div. The main tag is only meant to be used once in a document. section has replaced the .row. article and aside are two different .column classes.

CSS
main {
  max-width: 1200px;
  margin: 0 auto;
}
section {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
article,
aside {
  flex-basis: 100%;
}
@media screen and (min-width: 800px) {
  aside {
    flex: 2.5;
  }
  article {
    flex: 7.5;
  }
}

And now you have a perfectly functional, semantic layout based on Flexbox!

Thank you for reading! I'm Tania Rascia, and I write no-nonsense guides for designers and developers. If my content has been valuable to you, please help me keep the site ad-free and continuously updated with quality tutorials and material by making a donation. Any amount helps and is greatly appreciated! Otherwise, let me know any ideas you have on a course you'd be eager to see.

Write a response

Your email address will not be published.

Discussion

  • Ben says:

    This is a fantastic tutorial! One thing I struggled with, and maybe this will help someone else out…

    When combining irregular sections like”flex: 2.5″ with unspecified flex sections, my borders weren’t quite lining up. In your Codepen the section labeled “Seventy Five” doesn’t match up with the section labeled “25%”… Same problem.

    After some searching, I changed it to “flex: 25%” and it matches up correctly. Not sure if that’s proper markup, but seems to work.

  • Svetoslav Todev says:

    (Sorry: Once again because of html filtering)
    Nice article!
    Just one note and question at the same time:
    Why every single flexbox based grid on the web can not escape the usage of “row” extra tag when nesting?

    Flexbox model allows on each flex container to be flex item at the same time.

    Here an Example with nesting without second “row” element will produce same results:
    =================================
    /div class=”row”/

    – – /div class=”column row”/- two classes combined for flex container and flex-item at the same time
    – – – /div class=”column”/ Nested /end-div/
    – – – /div class=”column”/ Nested /end-div/
    – – /end-div/

    – – /div class=”column”/Nothing Nested/end-div/
    /end-div/
    =================================
    I think only reason to have extra tag with “row” class is if we must place some verticals gutters on rows that can conflict if the column has as well vertical gutters, but this is very rare case and is simple to make only with columns, not the rows.

  • Svetoslav Todev says:

    Nice article!
    Just one note and question at the same time:
    Why every single flexbox based grid on the web can not escape the usage of “row” extra tag when nesting?

    Flexbox model allows on each flex container to be flex item at the same time.

    Here an Example with nesting without second “row” element will produce same results:

    Nested

    Nested

    Nothing Nested

    I think only reason to have extra tag with “row” class is if we must place some verticals gutters on rows that can conflict if the column has as well vertical gutters, but this is very rare case and is simple to make only with columns, not the rows.

  • Mika Kaakinen says:

    Good, well-written basic tutorials are always needed. Everybody is a beginner at some point of time. I do not know much about Flexbox, but I am trying to get to know it. Thanks Tania for your work.

  • Philip Harper says:

    OMG. ????
    A simple concept, explained even simpler.

    This is brilliant.

    (again)

  • Amir says:

    Hi Tania,
    THANK YOU for such a nice post. Very useful tutorial. Just one thing, I think class _75 was missing in your css file.

    ._75 {
    flex: 7.5;
    }

  • Anh Tran says:

    Hi Tania, great post! Do you know the best way to set gutter between columns?

  • Wow! How can someone write this nicely! So awesome! Clean and succinct. Thank you!

  • Hi Tania,
    I really love how you write, your posts are so clear and well written.

    Thanks for make this flex-grid very simple. And if I want some margin for each column?

    Normally I do:

    .column {
    margin-right: 2%;
    }
    .column:last-child {
    margin-right: 0;
    }

    Is the same with your grid?

    Thanks 🙂

    • Tania says:

      Andrea, I prefer not to use margins, but rather padding based grids. If you put the margins in a div inside of your grid, you don’t have to worry about the margins messing with your percentages.

  • Tobe says:

    Hi Tania,

    wanted to ask what you think about this blog post:
    https://jakearchibald.com/2014/dont-use-flexbox-for-page-layout/

    Do you use flexbox for overall page layout on your current projects?

    Kind Regards
    Tobe

    • Tania says:

      Hi Tobe,

      I currently use Flexbox. It has very good support in all modern browsers, so it really depends on if you’re working for a company that needs to have legacy IE support. Here are the browser support specs. I also have a version of the same grid in floats, so it’s not an issue if I need to use that instead. However, I do use Flexbox for layout, and haven’t had any of the issues described in that blog post.

      This website, for example, doesn’t require any grid, but I am using flex for the header. The grid layout is only available in IE/Edge, so that one will have to wait.

      Hope that helps!

Tania's List

My tutorials, guides, and articles for web designers, developers, and autodidacts, sent out once a month or so. No bullshit, ads, or tricks.