'How to justify content with space-between AND have everything centered?

I'm running into a problem with flexbox.

I have a div that has a max-width of 920px. I want the boxes of content to fill up the div from left to right to the max possible width, with everything having equal margins. When the screen-size goes down to one box per row, I want that box to be centered on the screen.

Here is the site in action: http://javinladish.com/code/index.html

If I use:

justify-content: center;

Then the boxes don't fill up the max width.

If I use:

justify-content: space-between;

Then the boxes don't stay centered when I go down to one box per row.

How can I achieve a happy balance between the two? I.e filling up the max width of the container, and keeping all content centered?



Solution 1:[1]

The best solution would be to use margin: auto; on the flex items horizontal margins as follows:

    .flexbox {
       background-color: pink;
       display: flex;
       justify-content:  space-between;
       flex-wrap: wrap;
    }
    .flex-item {
       width: 175px;
       height: 175px;
       background-color: grey;
       margin: 10px auto;
    }
    <div class="flexbox">
       <div class="flex-item"></div>
       <div class="flex-item"></div>
       <div class="flex-item"></div>
       <div class="flex-item"></div>
       <div class="flex-item"></div>
       <div class="flex-item"></div>
       <div class="flex-item"></div>
    </div>

The only problem might be if the last row would have more than one item but not enough to fill up the whole row, there will be a lot of space between the last row items.

Solution 2:[2]

Seems you're after two behaviours at once. I've had success with justify-content: center and flex-wrap: wrap on the container, and setting an appropriate left and right margin on the children. Then apply that same amount as a negative margin on the container, and the edges of the children will line up with the container.

.parent {
    display: flex;
    flex-direction: row;
    justify-content: center;
    flex-wrap: wrap;
    margin: 0 -3rem;
}

.child {
    align-self: center;
    margin: 0 3rem 6rem 3rem;
}

Solution 3:[3]

justify-content: space-between; will always push the items apart to the very edges of the container per row. Any elements on another row would never be centered.

I've had success with negative margins, but this would imply that you explicitly set those margins:

JS Fiddle example

HTML

<div class="grid">
  <div class="grid__elem">
    TEST 1
  </div>
  <div class="grid__elem">
    TEST 2
  </div>
  <div class="grid__elem">
    TEST 3
  </div>
  <div class="grid__elem">
    TEST 4
  </div>
  <div class="grid__elem">
    TEST 5
  </div>
  <div class="grid__elem">
    TEST 6
  </div>
  <div class="grid__elem">
    TEST 7
  </div>
</div>

SCSS

.grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  margin-left: -2%;
  &__elem {
    width: 18%;
    background: red;
    color: white;
    margin: 0 0 2% 2%;
  }
}

There's also an option to target specific elements via align-self, but I've found this not useful in working examples. See this link.

Solution 4:[4]

Another approach would be to have a flex parent element that centers all the childs elements and then separate them by using margins.

In case you want to have independent margins for each element just create an specific class for each one.

.box{
  display:flex;
  justify-content:center;
}
.box > div{
  margin: 5px 20px 5px 20px;
}
<div class='box'>
  <div>[item one]</div>
  <div>[item two]</div>
  <div>[item three]</div>
</div>

Solution 5:[5]

The solution is to set the same width on each item so they occupy the same space and then they would be centered as you wish.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2
Solution 3
Solution 4
Solution 5 Mathieu Rios