Filling the Space in the Last Row with Flexbox

Chris Albrecht posted a question on StackOverflow about grids. Essentially: image you have an element with an unknown number of children. Each of those children is some percentage of the width of parent such that they make equal rows, like 25% wide each for four columns, 33.33% wide each for three columns, etc. The goal is to fill the space of this “grid” evenly. There are an unknown number of children, so let’s say you were going with 25% and there were 7 children, that would be 4 in the first row and 3 in the second. Chris needed the final 3 to adjust in width to fill the space, rather than leaving the gap.

Flexbox has just the answer for this, which would otherwise likely need to be a JavaScript intervention.

The solution is essentially making the children able to wrap with flex-wrap, and then filling the space with flex-grow.

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid-item {
  flex-grow: 1;
  min-width: 25%;
}

Here’s a visual example of that when each grid item is red and separated with a border:

By adjusting the min-width at different @media query breakpoints, you can make it responsive pretty easily:

.grid-item {
  flex-grow: 1;
  min-width: 25%;
}
@media (max-width: 1200px) {
  .grid-item {
    min-width: 33.33%; 
  }
}

Here’s that demo:

See the Pen Wrapping Flexbox with Media Query Widths by Chris Coyier (@chriscoyier) on CodePen.

If you like to balk at flexbox for not being ready to use yet, this example is for you, because flex-wrap wasn’t in Firefox at all until pretty recently, and isn’t even in stable yet, so probably not a super practical solution for Chris just yet. But remember Firefox auto-updates so when 28 rolls out everyone will have it pretty quickly. I’m still optimistic flexbox will be a pretty standard layout mechanism on new sites within a year or so.

If you only need flexbox for single-directional stuff, falling back to display: table is sometimes an option, if by fallback you mean to replicate the layout with some accuracy. If you need the wrapping, inline-block might work. You can test for flexbox wrapping support with:

@supports not (flex-wrap: wrap) {

}

And possibly fall back to inline-block (with no space between them) If you did that, here’s how you might adjust that last row if needed with JavaScript:

var leftovers = $(".child").removeAttr("style").length % 4;
  
if (leftovers > 0) {
  var newWidth = 100 / leftovers;
  var fromHere = $(".child").length - leftovers + 1;
  $(".child:nth-child(n+" + fromHere + ")").css("width", newWidth + "%");
}

Note the hard-coded 4 in there, which assumes 25% children. You could get fancier and detect that. I’ll leave that to you. Selecting the last few stragglers (determined by that modulus (%) operator) I did with a bit of an :nth-child recipe. Here’s a demo of it though:

See the Pen Wrapping Flexbox with Media Query Widths by Chris Coyier (@chriscoyier) on CodePen.

Remember there is a big ol’ guide to all the flexbox properties here.


Filling the Space in the Last Row with Flexbox is a post from CSS-Tricks

from CSS-Tricks http://ift.tt/PkOsa2

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s