36

Look at following fiddle https://jsfiddle.net/27x7rvx6

The CSS (#test is flexbox container, and .items are its children):

#test {
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  width: 300px;
  margin-left: 150px;
  border: 2px solid red;  
}
.item {
  flex: 0 0 70px;
  margin-right: 10px;
  background: blue;
  height: 70px;
  border: 2px solid black;
}

There is a one line (nowrap) flexbox with fixed size items. The container has justify-content set to center. Because the items can't shrink and are together wider than the container they start to overflow.

My problem is that the content overflows both to the left and to the right. Is there a way to make the content justified to center but once it starts to overflow make it act like the justify-content property is set to flex-start, resp. make it overflow only to right of the container?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Martin Kadlec
  • 4,702
  • 2
  • 20
  • 33
  • Nope....frankly, there is no method (using flexbox or not) to do this as it stands. CSS can't detect overflow like that. Maybe you could do something with an extra wrapper but it woud be funky – Paulie_D Dec 09 '15 at 17:00
  • Yeah I know there is no direct way to do it. One way to solve it if flexbox is not necessary is to use inline-blocks and text-align: center on the container, however I would like to solve this for flexbox. – Martin Kadlec Dec 09 '15 at 17:19

1 Answers1

89

justify-content is not the right approach to center because of the problem you describe.

Instead, I recommend auto margins. You can use them to center:

Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

And they behave as you want with overflow:

Overflowing boxes ignore their auto margins and overflow in the end direction.

For example, you can set margin-left: auto to the first flex item and margin-right: auto to the last one, or insert ::before and ::after pseudo-elements.

.test {
  display: flex;
  flex-flow: row nowrap;
  width: 200px;
  border: 2px solid red;
  margin: 10px;
}
.wide.test {
  width: 500px;
}
.test::before, .test::after {
  content: '';  /* Insert pseudo-element */
  margin: auto; /* Make it push flex items to the center */
}
.item {
  flex: 0 0 50px;
  margin-right: 10px;
  background: blue;
  height: 50px;
  border: 2px solid black;
}
<div class="test">
  <div class="item"></div><div class="item"></div><div class="item"></div>
  <div class="item"></div><div class="item"></div><div class="item"></div>
</div>
<div class="wide test">
  <div class="item"></div><div class="item"></div><div class="item"></div>
  <div class="item"></div><div class="item"></div><div class="item"></div>
</div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    Thanks. Note that for preventing weird overflow, a `max-width: 100%` etc may be useful – phil294 Feb 05 '19 at 23:38
  • @JosephMerdrignac yes it does – Vic Seedoubleyew Aug 19 '19 at 14:13
  • Does this example not show that it is not centering in the narrow version? Is there a way to center them when the inner elements are wider than the outer element? – bplittle Jun 12 '20 at 22:18
  • 3
    What if the parent has no width? – Kalnode Mar 04 '21 at 16:12
  • I know this is an old response, but this has solved a truly annoying issue I've spent hours on... Basically, if I used justify-content: center it created flex overflow that wasn't contained by the overflow: scroll property. So you could scroll only partially. I am applying margin auto instead on before/after pseudo and it fixed the annoyance. I use Flex to create "pagination" with pages hidden using overflow: hidden. But I also want scrollbars if a specific page is too big and is currently in the view. Hope that makes sense. – Jacky Prahec Jun 29 '23 at 12:06