Thoughts & Writings

Making a super flex cardlist

The caveats, the solutions and the fun

Published on

We've been pretty much bending over backwards building layouts. Using iframes, tables, inline-blocks & floats. But times have changes, and so have our toolsets. And now, until the moment where css grids lands in stable browsers, we have a new best friend: flexbox.

The "old" way using floats

I'll leave out the antiques, so we'll pick it up at floats. Using floats for a responsive card grid is usually hidden behind a nice clean class or mixin.. Just yank it in and it works right? But take a look at the code needed to create the float setup:

@media screen and (min-width: 23em) {
  .floats:after {
    content: "";
    display: table;
    clear: both;
  }
  .floats li {
    float: left;
    width: 50%;
  }
}
@media screen and (min-width: 23em) and (max-width: 40em) {
  .floats li:nth-child(odd) {
    clear: left;
  }
}
@media screen and (min-width: 40em) {
  .floats li {
    float: left;
    width: 33.33333%;
  }
}
@media screen and (min-width: 40em) and (max-width: 60em) {
  .floats li:nth-child(3n + 1) {
    clear: left;
  }
}
@media screen and (min-width: 60em) {
  .floats li {
    float: left;
    width: 25%;
  }
  .floats li:nth-child(4n + 1) {
    clear: left;
  }
}

The result is fine, but the code is pretty bulky right? With a lot of hacking going on with things like display: table and forced clear: left.

The "cool" way using flexbox

Flexbox might be a little snappy to get your head around at first – and might bite back a second time – but once tamed it's currently your best pal for building flexible and responsive layout systems. My rule of thumb: if something needs to be floated somewhere left or right in a text blob, use floats, but for anything layout use flexbox.

The bulky and tricky float setup can now be exchanged for the lean mean flexbox setup. Here come's the code:

.flexbox {
  display: flex;
  flex-wrap: wrap;
}
.flexbox > li {
  flex: 1 1 10em;
}

What this does is make all elements approximately 10em, growing or shrinking the items when needed. Best thing: There's no need for any media queries for this basic example. Right in line with the basic thought to "let the web flow". All items are distributed as efficiently as possible on any screensize. Scale your browser window to see the items adapt to the width.

Whoops, something looks awkward :-/

So there's a caveat: in this setup, using flex-grow (in the flex: 1 1 shorthand), flexbox grows each item to the max possible width in a row. So on a large screen there's a huge last element in this uneven set.

Solution 1: Flip

One solution – actually pretty cool looking – is to flip the order with flex-wrap: wrap-reverse:

Downside is that the order is... reversed. Which might not always be what you want. Ofcourse you could flip the order in the html, but good code semantics go before a good visual result. Reversing your html items is far from good semantics.

Solution 2: Pseudo element

Add a pseudo element with the max width you want the last item to shrink. So If you want the last item to shrink to 25% on desktop add a pseudo element with width 75%.

That's pretty flex right??

Don't stop there

Now that's just the top of the iceberg of flexbox usecases. Check out the "complete guide to flexbox" at css-tricks, do the online course "cracking the case with flexbox" at Codeschool or play around with some codepens about flexbox.