9

It seems that Chrome doesn't handle justify-content: space-around correctly when the content overflows the flex container, and the container is not set up to allow wrapping, but instead horizontal scrolling.

Some of the content overflows on the left side of the flex container, and is cut off. I want it to overflow on the right side, so that I can reach it by scrolling horizontally.

Here is an example:

#container {
  display: flex;
  width: 500px;
  justify-content: space-around;
  border: solid black;
  overflow: auto;
}
.item {
  min-width: 200px;
  margin: 10px;
  background-color: red;
  display: table;
  font-size: 48pt;
  text-align: center;
}
<div id="container">
  <div class="item">1</div><div class="item">2</div>
  <div class="item">3</div><div class="item">4</div>
  <div class="item">5</div><div class="item">6</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
ztforster
  • 1,369
  • 2
  • 10
  • 20

2 Answers2

15

That's because when there isn't enough space, space-around behaves like center:

If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to center.

And center behaves like you describe:

If the leftover free-space is negative, the flex items will overflow equally in both directions.

Instead, you can use space-between:

If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to flex-start.

Of course, then you won't have half-size spaces on neither end of the flex line. You can insert pseudo-element to have full-size spaces, though.

#container {
  display: flex;
  justify-content: space-between; /* Instead of space-around */
}
#container::before, #container::after {
  content: ''; /* Insert space before the first item and after the last one */
}

.container {
  display: flex;
  width: 500px;
  border: solid black;
  justify-content: space-between;
  overflow: auto;
  margin: 10px 0;
}
.container::before, .container::after {
  content: '';
}
.item {
  margin: 10px;
  background-color: red;
  display: table;
  font-size: 48pt;
  text-align: center;
}
.big > .item {
  min-width: 200px;
}
<div class="container big">
  <div class="item">1</div><div class="item">2</div>
  <div class="item">3</div><div class="item">4</div>
  <div class="item">5</div><div class="item">6</div>
</div>
<div class="container">
  <div class="item">1</div><div class="item">2</div>
  <div class="item">3</div><div class="item">4</div>
  <div class="item">5</div><div class="item">6</div>
</div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    Didn't know about that distinction between `space-around` and `space-between` when there is negative free space. So `space-around` resolves to `center`, and `space-between` resolves to `flex-start`. Pretty cool. But also quite arbitrary it seems. I guess the spec authors wanted to mix it up a little. Nice overall answer. – Michael Benjamin Dec 24 '15 at 16:41
  • @Michael_B Yes, I think it would have been better if there was another property to control the behavior when the free-space is negative. – Oriol Dec 24 '15 at 16:48
  • One more thing to note: Using the [original codepen demo](http://codepen.io/anon/pen/VeKmpM), if you simply disable the `min-width: 400px` rule in `.item`, it all works as intended with `space-around`. Similarly, switching `min-width` for `width` in the code posted in the question (which is different from the demo provided), `space-around` works. This seems to deviate from the spec. Maybe this has something to do with `display: table` applied to flex items. (Tested in Chrome) – Michael Benjamin Dec 24 '15 at 17:27
  • 1
    @Michael_B I think it's a bug in Chrome, I can't reproduce that on Firefox. Interestingly `flex-shrink: 0` fixes it, but `flex-basis: 0` breaks it again in weird ways. The cause seems `display: table` indeed. (BTW, when I edited the question I only made boxes smaller to fit SO better, and removed superfluous `width`) – Oriol Dec 24 '15 at 18:55
  • If you want `space-between` to overflow from the center when the content is too large for its container, wrap a container with `justify-content: space-between` inside another with `justify-content: center`. – northamerican Mar 09 '22 at 21:31
4

Since the container is limited in width and you want overflowing flex items to be accessed via horizontal scrolling, why use justify-content: space-around?

Try justify-content: flex-start:

Revised Codepen

To understand why overflowing flex items may be inaccessible via scroll, see this answer.

If you're interested in a Javascript workaround for the original code, see this post:

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    I apologize for not explaining this earlier. The contents of the container can be variable in width. When they fit inside of the container, I thought space-around looked better (i.e. more centered). However, I also need the container to degrade gracefully when the contents overflow. – ztforster Dec 24 '15 at 14:32
  • There is an issue when flex items overflow their container on the left (in horizontal mode) or the top (in vertical mode). The overflowing items may become inaccessible via scroll. This is a known issue with flexbox. I have posted a link in my answer that goes into further detail. – Michael Benjamin Dec 24 '15 at 14:42
  • 1
    Thanks for the links! Eventually, my solution will need to handle flex items which are variable width based on text within them (meaning I can't reliably calculate their width ahead of time). Therefore, it looks like auto margins are the way to go here (from your first SO link). – ztforster Dec 24 '15 at 14:55