66

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?

TylerH
  • 20,799
  • 66
  • 75
  • 101
javinladish
  • 907
  • 1
  • 9
  • 18
  • 2
    Have you tried `justify-content: space-around`? – Mathias Mar 05 '14 at 18:55
  • @Adrift That will have the same effect as `justify-content: space-around`, but it won't have the effect the OP is looking for (see comment below). – cimmanon Mar 05 '14 at 19:06
  • 1
    You could use media queries. @media screen and (max-width 580px) – Mathias Mar 05 '14 at 19:10
  • 1
    Looking at the page in question, you're going to have a hard time using Flexbox to accommodate mobile browsers since most of them don't support wrapping. You're going to have to choose a different way of solving this problem. – cimmanon Mar 05 '14 at 19:14
  • 1
    Try this: http://stackoverflow.com/questions/4771304/justify-the-last-line-of-a-div – cimmanon Mar 05 '14 at 21:18
  • 1
    @cimmanon There is no reason flexbox will have trouble accommodating mobile browsers. Most browsers don't support wrapping? I don't know even know what that means. http://caniuse.com/#feat=flexbox Please see answer below – StefanBob Apr 03 '17 at 19:13

6 Answers6

49

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.

Luke
  • 4,825
  • 2
  • 30
  • 37
martin schwartz
  • 863
  • 8
  • 17
  • 25
    The result is the same than `justify-content: space-around`, items are not reaching both sides. – stramin Oct 01 '19 at 21:10
  • 2
    it's usually around 2am after searching for 4 hours that a very small SO comment mentions the exact method you need when you've been square pegging a round hole - thank you – lys Mar 07 '21 at 16:31
  • 1
    This doesn't really work with more than one item on the final row – Libra Apr 23 '21 at 00:26
  • If you're using this method on a responsive layout, you may want to add horizontal padding to your flex-items to stop them getting too close before wrapping. – Harry B Aug 05 '21 at 10:59
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;
}

Isaac F
  • 199
  • 3
  • 7
1

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.

chocolata
  • 3,258
  • 5
  • 31
  • 60
-1

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>
Gass
  • 7,536
  • 3
  • 37
  • 41
-2
justifyContent: 'space-around'

resource: https://tproger.ru/translations/how-css-flexbox-works/

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • 1
    Welcome to Stack Overflow! Your answer links to a resource, but here at SO, answers should be self-sufficient. Along with the link, add the important content into your post and add detail to that content instead of just a direct copy-paste. That way, your answer would be more valuable and less likely to be deleted. Thanks for understanding. Here's [a help article](https://stackoverflow.com/help/how-to-answer) on how to write a good answer. – Lakshya Raj Jul 08 '22 at 22:58
  • 2
    You will need to explain your answers instead of relying 100% on link contents. Links get broken over time. – Lajos Arpad Jul 10 '22 at 14:33
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch Sep 18 '22 at 18:01
-3

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.

Mathieu Rios
  • 350
  • 1
  • 17