1

I'm trying to use justify-content to properly justify divs inside my container, but this option is not working the way I expected. I want my div's inside the container to keep order in the second row of my example like so:

1   2   3
4   5

and not like:

1  2  3
4     5

.container {
  display: flex;
  width: 1100px;
  justify-content: space-between;
  flex-wrap: wrap;
}
.container > div {
  width: 330px;
  height: 125px;
  background-color: rgba(18, 28, 41, 0.50);
  border: 1px solid #325E82;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Codepen: https://codepen.io/anon/pen/pryWYZ

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Src
  • 5,252
  • 5
  • 28
  • 56
  • 2
    You should use css grid for this. Flex is for displaying items in 1-demensionnal way, and you want to allign your items 2-dimensionnal. – Frilox Jul 31 '17 at 21:55
  • 1
    @Frilox thank you for advice! Just checked out what css grid is and it seems to be awesome for that kind of tasks. Gonna rewtire my code to use grids :D – Src Jul 31 '17 at 22:01

3 Answers3

3

One solution would be to make use of the pseudo-selector ::after in order to create a fake 'invisible' element that occupies the same width as the other elements. In combination with justify-content, this causes the existing final element to be moved to the center:

.container {
  display: flex;
  width: 1100px;
  justify-content: space-between;
  flex-wrap: wrap;
}

.container > div {
  width: 330px;
  height: 125px;
  background-color: rgba(18, 28, 41, 0.50);
  border: 1px solid #325E82;
}

.container::after {
  content: '';
  width: 332px; /* .container > div 'width' plus .container > div 'border' */
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

I've also created a CodePen of this here.

Hope this helps! :)

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • 1
    But, if i'll have for example 6 elements + after - it'll make new line... – Src Jul 31 '17 at 21:56
  • 1
    That's not a problem, considering the `::after` has zero `height` and no `content`. [**This example**](https://codepen.io/Obsidian-Age/pen/yoOPOZ) demonstrates that adding a sixth element would have no visible differences. I've set the background to red to help illustrate this :) – Obsidian Age Jul 31 '17 at 21:58
  • @ObsidianAge You'd better use `330px` for pseudoelement's `width` and apply `*, *:before, *:after { box-sizing: border-box; }` to get rid of this nasty calculations. – Vadim Ovchinnikov Aug 01 '17 at 17:43
1

Flexbox is not designed to create perfect grids. That's why aligning the flex items on the last row has no natural solution. You need hacks to make it work.

This is explained in detail in these posts:

The ideal way to solve this problem would be to switch from flex layout to grid layout. With CSS Grid Layout, there is more control over the placement and sizing of content items.

.container {
  display: grid;
  grid-auto-rows: 125px;
  grid-template-columns: repeat(auto-fill, 330px);
  grid-gap: 10px;
  width: 1100px;
}

.container>div {
  background-color: rgba(18, 28, 41, 0.50);
  border: 1px solid #325E82;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

For more details about CSS Grid, including an explanation of the properties above and browser support data, see this post: CSS-only masonry layout but with elements ordered horizontally

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Another way around it is to have justify-content: flex-start; on the .Container and specify margin on correct Child Items depending upon desired number of columns and restricting size on childs.

For a 3-Column grid, something like this:

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

.item {
  background-color: gray;
  width: 100px;
  height: 100px;
  flex: 0 0 32%;
  margin: 1% 0;
  
  }
  
  .item:nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
  }
  
<div class="container">
  <div class=item></div>
  <div class=item></div>
  <div class=item></div>
  <div class=item></div>
  <div class=item></div>
   
</div>
pk_code
  • 2,608
  • 1
  • 29
  • 33
  • It's not a good idea to use percentage margins (or paddings) on flex items. Currently, they are rendered differently across major browsers. For example, your solution works in Chrome but fails in Firefox. https://stackoverflow.com/q/36783190/3597276 – Michael Benjamin Aug 01 '17 at 03:02