[css] Flex-box: Align last row to grid

I have a simple flex-box layout with a container like:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Now I want the items in the last row to be aligned with the other. justify-content: space-between; should be used because the width and height of the grid can be adjusted.

Currently it looks like

The item in the bottom right should be in the middle

Here, I want the item in the bottom right to be in the "middle column". What is the simplest way to accomplish that? Here is a small jsfiddle that shows this behaviour.

_x000D_
_x000D_
.exposegrid {_x000D_
  display: flex;_x000D_
  flex-flow: row wrap;_x000D_
  justify-content: space-between;_x000D_
}_x000D_
_x000D_
.exposetab {_x000D_
  width: 100px;_x000D_
  height: 66px;_x000D_
  background-color: rgba(255, 255, 255, 0.2);_x000D_
  border: 1px solid rgba(0, 0, 0, 0.4);_x000D_
  border-radius: 5px;_x000D_
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);_x000D_
  margin-bottom: 10px;_x000D_
}
_x000D_
<div class="exposegrid">_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
  <div class="exposetab"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

This question is related to css flexbox grid-layout

The answer is


This version is best way for blocks with fixed width:

http://codepen.io/7iomka/pen/oxxeNE

In other cases - version of dalgard

http://codepen.io/dalgard/pen/Dbnus

_x000D_
_x000D_
body {_x000D_
  padding: 5%;_x000D_
}_x000D_
_x000D_
div {_x000D_
  overflow: hidden;_x000D_
  background-color: yellow;_x000D_
}_x000D_
_x000D_
ul {_x000D_
  display: flex;_x000D_
  flex-wrap: wrap;_x000D_
justify-content:center;_x000D_
  margin: 0 -4px -4px 0;_x000D_
  list-style: none;_x000D_
  padding: 0;_x000D_
}_x000D_
_x000D_
li {_x000D_
  flex: 1 0 200px;_x000D_
  height: 200px;_x000D_
  max-width:200px;_x000D_
  min-width:200px;_x000D_
  border-right: 4px solid black;_x000D_
  border-bottom: 4px solid black;_x000D_
  background-color: deeppink;_x000D_
}_x000D_
li:empty {_x000D_
  height: 0;_x000D_
  border: none;_x000D_
}_x000D_
_x000D_
*,_x000D_
:before,_x000D_
:after {_x000D_
  box-sizing: border-box;_x000D_
}
_x000D_
<div>_x000D_
  <ul>_x000D_
    <li>a</li>_x000D_
    <li>b</li>_x000D_
    <li>c</li>_x000D_
    <li>d</li>_x000D_
    <li>e</li>_x000D_
    <li>f</li>_x000D_
    <li>g</li>_x000D_
    <li>h</li>_x000D_
    <li>i</li>_x000D_
    <li>j</li>_x000D_
    <li>k</li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
  </ul>_x000D_
</div>
_x000D_
_x000D_
_x000D_


As other posters have mentioned - there's no clean way to left-align the last row with flexbox (at least as per the current spec)

However, for what it's worth: With the CSS Grid Layout Module this is surprisingly easy to produce:

Basically the relevant code boils down to this:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Make the container element a grid container

2) Set the grid with auto columns of width 100px. (Note the use of auto-fill (as apposed to auto-fit - which (for a 1-row layout) collapses empty tracks to 0 - causing the items to expand to take up the remaining space. This would result in a justified 'space-between' layout when grid has only one row which in our case is not what we want. (check out this demo to see the difference between them)).

3) Set gaps/gutters for the grid rows and columns - here, since want a 'space-between' layout - the gap will actually be a minimum gap because it will grow as necessary.

4) Similar to flexbox.

_x000D_
_x000D_
ul {_x000D_
  display: grid;_x000D_
  grid-template-columns: repeat(auto-fill, 100px);_x000D_
  grid-gap: 1rem;_x000D_
  justify-content: space-between;_x000D_
  _x000D_
  /* boring properties */_x000D_
  list-style: none;_x000D_
  background: wheat;_x000D_
  padding: 2rem;_x000D_
  width: 80vw;_x000D_
  margin: 0 auto;_x000D_
}_x000D_
_x000D_
li {_x000D_
  height: 50px;_x000D_
  border: 1px solid green;_x000D_
}
_x000D_
<ul>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_

Codepen Demo (Resize to see the effect)


One technique would be inserting a number of extra elements (as many as the max number of elements you ever expect to have in a row) that are given zero height. Space is still divided, but superfluous rows collapse to nothing:

http://codepen.io/dalgard/pen/Dbnus

_x000D_
_x000D_
body {_x000D_
  padding: 5%;_x000D_
}_x000D_
_x000D_
div {_x000D_
  overflow: hidden;_x000D_
  background-color: yellow;_x000D_
}_x000D_
_x000D_
ul {_x000D_
  display: flex;_x000D_
  flex-wrap: wrap;_x000D_
  margin: 0 -4px -4px 0;_x000D_
  list-style: none;_x000D_
  padding: 0;_x000D_
}_x000D_
_x000D_
li {_x000D_
  flex: 1 0 200px;_x000D_
  height: 200px;_x000D_
  border-right: 4px solid black;_x000D_
  border-bottom: 4px solid black;_x000D_
  background-color: deeppink;_x000D_
}_x000D_
li:empty {_x000D_
  height: 0;_x000D_
  border: none;_x000D_
}_x000D_
_x000D_
*,_x000D_
:before,_x000D_
:after {_x000D_
  box-sizing: border-box;_x000D_
}
_x000D_
<div>_x000D_
  <ul>_x000D_
    <li>a</li>_x000D_
    <li>b</li>_x000D_
    <li>c</li>_x000D_
    <li>d</li>_x000D_
    <li>e</li>_x000D_
    <li>f</li>_x000D_
    <li>g</li>_x000D_
    <li>h</li>_x000D_
    <li>i</li>_x000D_
    <li>j</li>_x000D_
    <li>k</li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
    <li></li>_x000D_
  </ul>_x000D_
</div>
_x000D_
_x000D_
_x000D_

In the future, this may become achievable through using multiple ::after(n).


Just add few fake items with same properties except for height set to 0px to the end.


If the individual child items have an explicit width (eg. 32%), you can solve this by adding an :after element to the parent and giving this the same explicit width.


There is a way without flexbox, although you'd need to meet the following conditions. 1) The container has padding. 2) Items are the same size and you know exactly how many you want per line.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

The smaller padding on the right side of the container allows for the extra padding to the right of each list item. Assuming other items in the same parent as the list object are padded with 0 5%, it will be flush with them. You can also adjust the percentages to however much margin you'd like or use calculate px values.

Of course, you can do the same without the padding on the container by using nth-child (IE 9+) to remove margin on every third box.


If you want a grid with some space between the items and the items starting without any initial space then this simple solution works:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

If you want the initial 5px space then just remove the negative margin :) Simple.

https://jsfiddle.net/b97ewrno/2/

The accepted answer, whilst good, it causes there to be no space between the elements on the second row..


Simply Use Jquery/Javascript trick to add an empty div:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}

I was able to do it with justify-content: space-between on the container


This is a combination of a lot of the answers but it does exactly what I was needing -- which is, aligning the last child in a flex container to the left while maintaining the space-between behavior (in this case it's a three-column layout).

Here's the markup:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}

If you want to align the last item to the grid use the following code:

Grid container

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Item in the grid

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

The trick is to set the max-width of the item equal to the max-width of the .card-grid:after.

Live demo on Codepen


This is pretty hacky, but it works for me. I was trying to achieve consistent spacing/margins.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/


Oh boy, I think I found a good solution with minimal CSS and no JS. Check it out:

_x000D_
_x000D_
img {width:100%;}_x000D_
li {_x000D_
  display: inline-block;_x000D_
  width:8em;_x000D_
  list-style:none;_x000D_
}_x000D_
ul {text-align: justify;}
_x000D_
<ul>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li>_x000D_
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />_x000D_
  </li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
  <li></li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_

The key here is to remember that what we are trying to achieve is exactly what text-align: justify does!

The empty elements in the HTML are there to make the last row display perfectly without changing the appearance, but might not be needed given what you are trying to achieve. For perfect balance in every situation, you need at least x-4 empty elements, x being the number of elements to display, or n-2, n being the number of column you want to display.


I made a SCSS mixin for it.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

This is the codepen link: http://codepen.io/diana_aceves/pen/KVGNZg

You just have to set the items width in percentage and number of columns.

I hope this can help you.


If you know the width of spaces between elements in the row and the amount of elements in a row, this would work:

Example: 3 elements in a row, 10px gap between elements

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}

you want to align

use align-content: flex-start; instead of justify-content: space-between;

this pulls the items last row to left , and also distributes space evenly,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


danAnderson solution is NOT DYNAMIC .PERIOD!!

when item width changed from 25 to 28 dan anderson fails space between images

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

dynamic: https://codepen.io/anon/pen/aQggBW?editors=1100

thats what ive been trying to say . dans is hacky.....


Here's another couple of scss mixins.

These mixins assume that you are not going to use js plugins like Isotope (they don't respect html markup order, thus messing up with css nth rules).

Also, you will be able to take full advantage of them especially if you're writing your responsive breakpoints in a mobile first manner. You ideally will use flexbox_grid() on the smaller breakpoint and flexbox_cell() on the following breakpoints. flexbox_cell() will take care of resetting previously setted margins no longer used on larger breakpoints.

And by the way, as long as you correctly setup your container's flex properties, you can also use only flexbox_cell() on the items, if you need to.

Here's the code:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Usage:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Obviously, it's up to you to eventually set container's padding/margin/width and cell's bottom margins and the like.

Hope it helps!


Yes.! We can but with some media queries & Maximum no of columns are predefined.

Here am using 4 columns. Check my code:

_x000D_
_x000D_
.container {_x000D_
  display: flex;_x000D_
  display: -webkit-flex;_x000D_
  display: -moz-flex;_x000D_
  flex-flow: row wrap;_x000D_
  -webkit-flex-flow: row wrap;_x000D_
  -moz-flex-flow: row wrap;_x000D_
}_x000D_
_x000D_
.container .item {_x000D_
  display: flex;_x000D_
  display: -webkit-flex;_x000D_
  display: -moz-flex;_x000D_
  justify-content: center;_x000D_
  -webkit-justify-content: center;_x000D_
  -moz-justify-content: center;_x000D_
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns_x000D_
}_x000D_
_x000D_
.container .item .item-child {_x000D_
  width: 130px;_x000D_
  height: 180px;_x000D_
  background: red;_x000D_
  margin: 10px;_x000D_
}_x000D_
_x000D_
@media (max-width: 360px) {_x000D_
  .container .item {_x000D_
    flex-basis: 100%;_x000D_
  }_x000D_
}_x000D_
_x000D_
@media (min-width:360px) and (max-width: 520px) {_x000D_
  .container .item {_x000D_
    flex-basis: 50%;_x000D_
  }_x000D_
}_x000D_
_x000D_
@media (min-width:520px) and (max-width: 680px) {_x000D_
  .container .item {_x000D_
    flex-basis: 33.33%;_x000D_
  }_x000D_
}
_x000D_
<div class="container">_x000D_
_x000D_
  <div class="item">_x000D_
    <div class="item-child">1</div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
  <div class="item">_x000D_
    <div class="item-child"></div>_x000D_
  </div>_x000D_
_x000D_
</div>
_x000D_
_x000D_
_x000D_

NOTE
1) No need to create child div. It may be any other tag like 'img' r whatever you want..
2) If you want more columns adjust the media queries and maximum no.of columns.


Assuming:

  • You want 4 column grid layout with wrapping
  • The number of items is not necessarily a multiple of 4

Set a left margin on every item except 1st, 5th and 9th item and so on. If the left margin is 10px then each row will have 30px margin distributed among 4 items. The percentage width for item is calculated as follows:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

This is a decent workaround for issues involving last row of flexbox.

_x000D_
_x000D_
.flex {_x000D_
  display: flex;_x000D_
  flex-direction: row;_x000D_
  flex-wrap: wrap;_x000D_
  margin: 1em 0 3em;_x000D_
  background-color: peachpuff;_x000D_
}_x000D_
_x000D_
.item {_x000D_
  margin-left: 10px;_x000D_
  border: 1px solid;_x000D_
  padding: 10px;_x000D_
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);_x000D_
  background-color: papayawhip;_x000D_
}_x000D_
_x000D_
.item:nth-child(4n + 1) {_x000D_
  margin-left: 0;_x000D_
}_x000D_
_x000D_
.item:nth-child(n + 5) {_x000D_
  margin-top: 10px;_x000D_
}
_x000D_
<div class="flex">_x000D_
  <div class="item">1</div>_x000D_
  <div class="item">2</div>_x000D_
  <div class="item">3</div>_x000D_
  <div class="item">4</div>_x000D_
</div>_x000D_
<div class="flex">_x000D_
  <div class="item">1</div>_x000D_
  <div class="item">2</div>_x000D_
  <div class="item">3</div>_x000D_
  <div class="item">4</div>_x000D_
  <div class="item">5</div>_x000D_
  <div class="item">6</div>_x000D_
</div>_x000D_
<div class="flex">_x000D_
  <div class="item">1</div>_x000D_
  <div class="item">2</div>_x000D_
  <div class="item">3</div>_x000D_
  <div class="item">4</div>_x000D_
  <div class="item">5</div>_x000D_
  <div class="item">6</div>_x000D_
  <div class="item">7</div>_x000D_
  <div class="item">8</div>_x000D_
  <div class="item">9</div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


Even though gap is coming to Flexbox I will add a solution that works.

It uses the sibling combinator to check 2 conditions.

The first condition it checks is if an element is the second to last div:nth-last-child(2)

For 4 column layouts we need to check for postions 2 & 3 Check if it is in the second row of 4 div:nth-of-type(4n+2) or third in a row div:nth-of-type(4n+3)

For 3 column layouts we only need to check position 2

div:nth-of-type(3n+2)

We can then combine like below for 4 column layouts

div:nth-last-child(2) + div:nth-of-type(4n+2)

div:nth-last-child(2) + div:nth-of-type(4n+3)

We also need to take care of one edge case, Any number that is 3n+2 & multiple of 4 will get the 35% margin-right div:nth-last-child(2) + div:nth-of-type(4n+4)

3 column layouts will be

div:nth-last-child(2) + div:nth-of-type(3n+2)

Then we need to add a margin to the above selectors. The margin-right will need to be calculated and will depend on the flex-basis.

I have added a sample with 3 and 4 columns and a media query. I have also added a small JavaScript button that adds a new div so you can check it works.

It is a little bit of CSS but it works. I also wrote about this on my site if you want a little more explanation. https://designkojo.com/css-programming-using-css-pseudo-classes-and-combinators

_x000D_
_x000D_
var number = 11;

$("#add").on("click", function() {
    number = number + 1;
    $("#main").append("<div>" + number + "</div>");
});
_x000D_
body {
  margin: 0;
}
main{
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  align-content: flex-start; /* vertical */
  justify-content: space-between;
  min-width: 300px;
  max-width: 1200px;
  margin: 20px auto;
  background-color: lightgrey;
  height: 100vh;
}
div {
  flex-basis: 30%;
  background-color: #5F3BB3;
  min-height: 20px;
  height: 50px;
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #9af3ff;
  font-size: 3em;
}


div:nth-last-child(2) + div:nth-of-type(3n+2) {
  background-color: #f1b73e;
  margin-right: 35%;
}

@media screen and (min-width: 720px) {

  div {
    flex-basis: 22%;
  }

  div:nth-last-child(2) {
    background-color: greenyellow;
  }

  div:nth-of-type(4n+2) {
    background-color: deeppink;
  }

  /* Using Plus combinator is for direct sibling */
  div:nth-last-child(2) + div:nth-of-type(4n+2) {
    background-color: #f1b73e;
    margin-right: 52%;
  }

  div:nth-last-child(2) + div:nth-of-type(4n+3) {
    background-color: #f1b73e;
    margin-right: 26%;
  }

  /* Also need to set the last to 0% to override when it become (3n+2)
   * Any number that is 3n+2 & multiple of 4 will get the 35% margin-right
   * div:nth-last-child(2) + div:nth-of-type(3n+2)
   */

  div:nth-last-child(2) + div:nth-of-type(4n+4) {
    background-color: #f1b73e;
    margin-right: 0;
  }

}
_x000D_
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>My New Project</title>
</head>

<body>

<header>


</header>

<button id="add">Add</button>
<main id="main">

  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
  <div>11</div>


</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="action.js"></script>
</body>
</html>
_x000D_
_x000D_
_x000D_


Using flexbox and a few media queries, I made this little work-around: http://codepen.io/una/pen/yNEGjv (its a bit hacky but works):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}

You can't. Flexbox is not a grid system. It does not have the language constructs to do what you're asking for, at least not if you're using justify-content: space-between. The closest you can get with Flexbox is to use the column orientation, which requires setting an explicit height:

http://cssdeck.com/labs/pvsn6t4z (note: prefixes not included)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

However, it would be simpler to just use columns, which has better support and doesn't require setting a specific height:

http://cssdeck.com/labs/dwq3x6vr (note: prefixes not included)

ul {
  columns: 15em;
}

Seems like no one proposed the flex-grow solution on last item. The idea is to have your last flex item to take all the place it can using flex-grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Note: This solution is not perfect, especially if you have centered elements inside your flex items as it will center on the possibly huge last flex item.


I modified the example presented by Dan Andreasson by using a right border on elements to create a faux gutter. You can then use nth-child to remove the border on the last-child of the column grid count you need. here is a demo https://codepen.io/JacobLett/pen/mdVoroM

_x000D_
_x000D_
/* demo only */
body {
margin:0;
padding:0;
max-width:1024px;
margin:0 auto;
}
.block-list {
background: #ccc;
  border:1px solid #ccc;
}

.block-list .block-list__item {
background: #eee;
}
/* demo only */




.block-list .block-list__item {
   min-height: 100px;
   margin-bottom: 1rem;
}

@media only screen and (min-width: 900px) {
   .block-list {
      display: -webkit-box;
      display: flex;
      flex-wrap: wrap;
      -webkit-box-pack: justify;
      justify-content: space-between;
      background-color: #ffffff;
      margin: 1em auto;
   }

   .block-list:after {
      content: "";
      -webkit-box-flex: 1;
      flex: auto;
   }

   .block-list__item {
      height: 10em;
      width: 25%;
      box-sizing: border-box;
      border-right: 10px solid white;
   }

   .block-list-2 .block-list__item {
      width: 50%;
   }

   .block-list-2 .block-list__item:nth-child(2n) {
      border: none;
   }

   .block-list-3 .block-list__item {
      width: 33.3%;
   }

   .block-list-3 .block-list__item:nth-child(3n) {
      border: none;
   }

   .block-list-4 .block-list__item {
      width: 25%;
   }

   .block-list-4 .block-list__item:nth-child(4n) {
      border: none;
   }
   
   .block-list-5 .block-list__item {
      width: 20%;
   }

   .block-list-5 .block-list__item:nth-child(5n) {
      border: none;
   }
   
   .block-list-6 .block-list__item {
      width: 16.66%;
   }

   .block-list-6 .block-list__item:nth-child(6n) {
      border: none;
   }
}
_x000D_
<h2>2 column</h2>
<div class="block-list block-list-2">
   <div class="block-list__item">1
   </div>
   <div class="block-list__item">2
   </div>
   <div class="block-list__item">3
   </div>
   <div class="block-list__item">4
   </div>
   <div class="block-list__item">5
   </div>
   <div class="block-list__item">6
   </div>
</div>
<h2>3 column</h2>
<div class="block-list block-list-3">
   <div class="block-list__item">1
   </div>
   <div class="block-list__item">2
   </div>
   <div class="block-list__item">3
   </div>
   <div class="block-list__item">4
   </div>
   <div class="block-list__item">5
   </div>
   <div class="block-list__item">6
   </div>
</div>

<h2>4 column</h2>
<div class="block-list block-list-4">
   <div class="block-list__item">1
   </div>
   <div class="block-list__item">2
   </div>
   <div class="block-list__item">3
   </div>
   <div class="block-list__item">4
   </div>
   <div class="block-list__item">5
   </div>
   <div class="block-list__item">6
   </div>
</div>
<h2>5 column</h2>
<div class="block-list block-list-5">
   <div class="block-list__item">1
   </div>
   <div class="block-list__item">2
   </div>
   <div class="block-list__item">3
   </div>
   <div class="block-list__item">4
   </div>
   <div class="block-list__item">5
   </div>
   <div class="block-list__item">6
   </div>
</div>
<h2>6 column</h2>
<div class="block-list block-list-6">
   <div class="block-list__item">1
   </div>
   <div class="block-list__item">2
   </div>
   <div class="block-list__item">3
   </div>
   <div class="block-list__item">4
   </div>
   <div class="block-list__item">5
   </div>
   <div class="block-list__item">6
   </div>
</div>
_x000D_
_x000D_
_x000D_


I know there are many answers here but.. The simplest way to do this is with a grid instead of flex and grid template columns with repeat and auto fills, where you have to set the number of pixels that you have given to each element, 100px from your snippet code.

_x000D_
_x000D_
.exposegrid {_x000D_
     display: grid;_x000D_
     grid-template-columns: repeat(auto-fill, 100px);_x000D_
     justify-content: space-between;_x000D_
}_x000D_
 .exposetab {_x000D_
     width: 100px;_x000D_
     height: 66px;_x000D_
     background-color: rgba(255, 255, 255, 0.2);_x000D_
     border: 1px solid rgba(0, 0, 0, 0.4);_x000D_
     border-radius: 5px;_x000D_
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);_x000D_
     margin-bottom: 10px;_x000D_
}
_x000D_
<div class="exposegrid">_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
   <div class="exposetab"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


This problem was solved for me using CSS grid,

This solution is applicable only if you're having fix number of columns i.e. no. of elements to display in a single row

-> using grid but not specifying number of rows, as number of elements increase it wraps into columns and add rows dynamically, I have specified three columns in this example

-> you don't have to give any position to your child/cells, as it will make it fix, which we don't want.

_x000D_
_x000D_
.grid-class{_x000D_
  display: grid;_x000D_
  grid-template-columns: repeat(3, 1fr);_x000D_
  column-gap: 80px;_x000D_
}
_x000D_
_x000D_
_x000D_


Without any extra markup, just adding ::after worked for me specifying the width of the column.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

With the HTML like this:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>

It is possible to use "flex-start" and to add the margins manually. It requires some math-hacking but is definitely easy to do and make it easy to use with a CSS preprocessor like LESS.

See for example this LESS mixin:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

And then it can easily be used to display a responsive grid layout:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Here is an example of

http://codepen.io/anon/pen/YyLqVB?editors=110


A possible solution is to use justify-content: flex-start; on the .grid container, size restrictions on its children, and margins on the appropriate child elements -- depending on the desired number of columns.

For a 3-column grid, the basic CSS would look like this:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

It's another imperfect solution, but it works.

http://codepen.io/tuxsudo/pen/VYERQJ