loading...
Cover image for Ridiculously easy row and column layouts with Flexbox

Flex Two Columns Ridiculously easy row and column layouts with Flexbox

drews256 profile image Andrew Stuntz ・4 min read

Super easy responsive Row and Columns in straight up CSS

Grid layouts are the bread and butter of web development design and chances are you've reached for something like Bootstrap or Foundation to make your layouts a reality. But, like most of you, I don't have a fondness of the dependencies required to run Bootstrap or Foundation nor do I like the ding to my page load times.

In fact when I use Bootstrap for an application that I am writing, I really almost only ever use it for the grid layouts, sometimes I will use it for notifications or basic fairly sensible CSS defaults, but 90% of the time, all I want is the grid layouts.

I also don't appreciate only have options of splitting columns into 12 columns or less. It feels like you sometimes have to do some crazy work arounds to get columns in columns, or strange things like that.

How can we do grid layouts faster and easier? Flexbox is your answer. I think

Flexbox

At this point flexbox is pretty much everywhere. It's supported by all major browsers. It allows for much easier layouts and is supported by React-Native which means when I layout pages for React-Native I reach for flexbox first, but I have found my self reaching for flexbox first in web development as well.

In fact the last application I laid out, I did entirely with flexbox. I have found it that easy to use.

If you don't know too much about flex box. I like this page that gives a good run down of flexbox

Layout

First I wrap the entire page in a div.

<div class='some-page-wrapper'>
</div>

Then I define a .row and .column class that can help with the layout.

.row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 100%;
}

.column {
  display: flex;
  flex-direction: column;
  flex-basis: 100%;
  flex: 1;
}

Now if we want a two column layout:

<div class='some-page-wrapper'>
  <div class='row'>
    <div class='column'>
      <div class='blue-column'>
        Some Text in Column One
      </div>
    </div>
    <div class='column'>
      <div class='green-column'>
        Some Text in Column Two
      </div>
    </div>
  </div>
</div>

The CSS looks like:

.some-page-wrapper {
  margin: 15px;
  background-color: red;
}

.row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 100%;
}

.column {
  display: flex;
  flex-direction: column;
  flex-basis: 100%;
  flex: 1;
}

.blue-column {
  background-color: blue;
  height: 100px;
}

.green-column {
  background-color: green;
  height: 100px;
}

What if we wanna add a third column? The HTML is easily updated to:

<div class='some-page-wrapper'>
  <div class='row'>
    <div class='column'>
      <div class='blue-column'>
        Some Text in Column One
      </div>
    </div>
    <div class='column'>
      <div class='green-column'>
        Some Text in Column Two
      </div>
    </div>
    <div class='column'>
      <div class='orange-column'>
        Some Text in Column Two
      </div>
    </div>
  </div>
</div>

And we get a third column added. That seamlessly nests itself in our row.

Now what if we want more complicated layouts?

We can just add more rows, that is pretty easy.

<div class='some-page-wrapper'>
  <div class='row'>
    <div class='column'>
      <div class='orange-column'>
        Some Text in Column One
      </div>
    </div>
    <div class='column'>
      <div class='blue-column'>
        Some Text in Column Two
      </div>
    </div>
    <div class='column'>
      <div class='green-column'>
        Some Text in Column Three
      </div>
    </div>
  </div>
  <div class='row 2'>
    <div class='column'>
      <div class='green-column'>
        Some Text in Row 2, Column One
      </div>
    </div>
    <div class='column'>
      <div class='orange-column'>
        Some Text in Row 2, Column Two
      </div>
    </div>
    <div class='column'>
      <div class='blue-column'>
        Some Text in Row2, Column Three
      </div>
    </div>
  </div>
</div>

Or we can resize our columns.

To have a double column we can add a .double-column class. This can work with any sized column though, you can do 60/40, you can do 10/10/10/10/10/10/10/10/10/10, honestly any combination is possible here. You can do 1 X 100. Or 10 x 1, then 20 x 3, then 30 x 1. The options are endless!

On one layout, I added a large margin around my "column" and since the row will wrap down, I have one row with as many "columns" as I need. The columns were fixed width cards so they just wrap to the next line and flexbox neatly responsively wraps the cards down the screen.

.double-column {
  display: flex;
  flex-direction: column;
  flex-basis: 100%;
  flex: 2;
}

This isn't very responsive though? We can add some responsitivity using media queries.

Just move the flex: 1 and flex: 2 into a media-query (size depends on application I'm just giving an option)

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

  .double-column {
    flex: 2
  }
}

At > 800px:

large responsive at greater than 800

At < 800px:

resonsive at less than 800

The final codepen, hint click the 1x or 0.5x buttons in the lower right corner to see the difference in the "responsive" layout.

Essentially we just blew the row/columns of bootstrap out of the water with 20 lines of CSS. We have a way to create row/column layouts quickly and since we use flexbox we barely have to worry about the layouts breaking, or anything going wrong. It's easily adapted to a wide variety of uses and allows a large amount of customizability. What do you think about flexbox? Have you tried it yet?

Another hidden benefit is that if I layout React components in this way, its pretty easy to layout React-Native components very easily to look similar.

I usually use SCSS in my projects so if you see something that isn't perfect CSS let me know!

Posted on by:

drews256 profile

Andrew Stuntz

@drews256

I'm a full stack developer working on building web applications for all sorts of sized companies using a wide variety of web technologies. Mostly working in Ruby and JavaScript.

Discussion

markdown guide
 

Nice writeup. Here's some fun katas sites for Flexbox for those interested:

CSS Grid is starting to become mainstream and if you don't need to worry about legacy browsers, it's definitely the way to go for layout. Having said that, we've started using css grid at work, but Flexbox is still very useful.

I've started watching Jen Simmons' YouTube series. It's another great CSS resource. Here's a relevant video.

Cheers and looking forward to your next post!

 

Thank you!

Yesss. I am so psyched about grid becoming more fully supported. I don't even consider myself too much of a front end expert and I look forward to getting to use grid. I will consider it more seriously the next time I work on something new!

 

πŸ‘

@wesbos has a great CSS Grid course if you're interested.

Yeah check out @wesbos ' JavaScript30.com. He also has a great free course thanks to Mozilla on CSS Grid. Check out cssgrid.io. If you enjoy listening to podcasts, Wes and Scott "El Toro Loco" Tolinski have a great one called Syntax. And lastly, he did an AMA on dev.to a while back that might interest you.

 

Thank you Andrew.

I've never thought about giving meaningful class names such as rows & columns.

It just made CSS much more readable.

 

Haha, I know there are many people with many ideas about how to name classes and ID's in HTML and CSS. I have yet to use anything that I liked enough to stick with. So, I go with "sensible" and "meaningful" class names. But It sometimes still feels unorganized. One of the biggest reasons I like to use the above to layout pages, is that I can scope all my SASS to the outer level div, and that can help keep things organized. My opinions on class naming are evolving though, maybe I should write something about that next!

 

My opinions on class naming are evolving though, maybe I should write something about that next!

I'd love to read about it β€οΈπŸ•Ί

 

A great CSS library built around flexbox is Flex Layout Attribute. It saves lot of time with shorthands and also ships with responsive classes.

FLA

Flexbox is so "flexible" that once you start using it you won't need anything else for layouts.

 

Ohhh. I'll have to check this out.

 

I used to despise CSS for how complicated I found to set up a simple grid structure but this article made it super easy to understand. Thank you for this! I will definitely be referencing this in the future.

 

Definitely referencing this in my resource list my company is putting together!

Thanks Andrew :)

 

This is the best feedback! Thanks!

 

You've now inspired me to write up some cool stuff like this but for Sass. You da man.

 

I only have one simple question.
Why do you have:

display: flex;
flex-direction: column;

in .column?
Isn't this only if the column itself contains flex elements?

 

That's what I was wondering.

I'm not an expert, but from this article, I understand that some flex properties are for flex parents, and some are for flex children.

So in this case, no need for any flex parent properties on the flex children.

Here's the last example on the page with extra properties commented-out - works just the same:

codepen.io/mindplay-dk/pen/oNXmwej

So all we need is this:

.row {
  display: flex;
  flex-wrap: wrap; /* only needed for responsive */
  width: 100%;
}

.column {
  flex-basis: 100%;
}

Also note that flex-wrap: wrap on the .row is only needed for responsive layouts - if you don't have any responsive rules, you don't need this, since nowrap is the default, and columns will divide the space and never wrap.

 

I am no expert either, but I have worked on the CSS a lot... here is the result:

codepen.io/mercmobily/pen/KKddYNJ

Basically:

  • The default CSS rules are set for the "large" layout; the "exception" is for small screens
  • That "flex: 1" actually means flex-grow : 1; flex-shrink : 1; flex-basis : 0; (courtesy of stackoverflow.com/questions/373862...). I set those values as defaults for every columns and...
  • Changed the CSS so that every column has the class 'column', but adding s2 or s3 makes them wider

I am not 100% sure when we would ever want to use flex-wrap: wrap;. However, I left it there.

I basically spelt every out in terms of CSS rules, and "reversed it out" to make it easier to understand.

Would you consider updating the article with this updated CSS? If not, I will be happy to write an article about it (obviously linking back to you!)

I didn't write the article, just a comment πŸ™‚

Wrong link? the link you posted is just a link to the codepen I posted? πŸ˜‰

I didn't write the article, I just wrote a comment πŸ™‚

(Also, wrong link? The link you posted is just a link to the codepen I posted.)

Ah I thought you were the author -- sorry!
I updated my comment with the correct link. Well spotted. I nearly had a heart attack, thinking that I had lost it!

 

Thanks Andrew,

This has been very helpful to me mostly because of the live examples.

As I was playing around with it. I wanted to try a layout with one row that contains three columns of different widths. In the third column are two rows.

I was able to get column 1 & 2 to have their own custom widths by using SASS and moving the custom class name to the same div the column class was declared, as you'll see in my example below.

But I was not able to get the third column to contain two rows. Could you offer any advice?

 

thanks for the tutorial, this is great. One question i have though is there a way to break a 2 row 3 column grid into a 3 row 2 column grid at say 960px wide and then to a one column grid at less than 768 wide?

 

Thanks for the example-driven post. Super great resource.

 

It’s actually a nice and helpful piece of info. I am happy that you simply shared this helpful info with us. row vs column

Please keep us informed like this. Thanks for sharing.

 

As mentioned by others indeed a nice article.

I think the introductory note about Bootstrap and Foundation really made sense to me. I'd to create a mocks for my engineering team and I was looking for a tool. Bootstrap is so well known that I downloaded it but wasn't sure the value it would provide if my mock is simple. Your introductory paragraphs made a lot of sense to me.

Thank you.

 

Cool tutorial.

What if we wanna add a third row?

Think you mean "column". And the next paragraph, too, refers to "row" instead "column".

 

Whoops. Thanks for the catch.

 

I use Bulma CSS for this kind of stuff - any other good libraries out there that support flexbox or simil?

 

Great tutorial! I really appreciate it. Probably will change the way I build sites.

 

I needed this today, great timing!

 

Thanks for the great article and examples. I've just started reading about flex box on MDN. This article really helped me understand it.

 

Yeah, I am glad it is helping! This is just one example of how to use flexbox though it is very powerful if you play with it a little bit. Flexbox has really helped me step up my front end skills. It makes things like centering and aligning trivial as long as you think about your layout a little bit before you put any code down.

 

... and wrapping it in a form will break it.

 

Great example, I would recommend a little grid framework, for the not that front end developer, that don't want to use bootstrap.
daneden.github.io/Toast/

 

I've heard of toast, but I haven't used it. I'll dive in!

 

Thank you! I am new to web developing and I appreciate articles like yours that break things down in an easy to follow way.

 

Great article!
I'm stuck with flex-basis. I don't understand it purpose in general. I make some changes to its values on codepen but I still can't get it. Can you explain please?

 

You're a life saver... Thank you😊

 

Found this today and used it for my portfolio site, cannot thank you enough! Great use of flexbox and a well-written, informative, and clear example-led tutorial. Really fab stuff. :)

 

This is true mastery in flex stuff man

 

How we can add space between columns and bottom row margin

 

That's what I'd like to know. πŸ€”

I've seen one CSS library that uses the approach with just row, column and "double column", "half column" etc. classes. - it doesn't work and I'm not convinced it's possible without resorting to selectors like e.g. row.margin-20 > column with potentially specificity problems, and... suddenly things don't look that simple.

Of course, one option is to use another element to establish margins, e.g.:

<div class="row">
  <div class="column">
    <div class="margin-20">...</div>
  </div>
  <div class="column">
    <div class="margin-20">...</div>
  </div>
</div>

The problem with that of course is less elegant markup with extra elements, plus you have to carefully manage your column-margin elements and make sure they're all still the same width if you make changes, so... Not really a good approach either.

EDIT: these days, I'm taking an approach with more utility-classes, and by now I disagree with my last statement here. By now, I find that row and column being solely responsible for dividing into rows and columns, actually makes sense - I don't actually want any built-in padding or margins in grids, because this makes it harder to, say, fill a cell with a background, or use more/less whitespace in a particular cell, etc... So by now, I actually prefer the approach where another element is nested to add padding or background.

 

Looking for a way to have the text flow into the next column in a responsive way. Like a two-column magazine layout would. I'm not sure that's even possible.

 
 

That's pretty straightforward challenge comes when you have nested columns/ equal height content column/ background images.