7

I have a flex-based unordered list of social media icons at the bottom of a mobile menu on my website.

I'm trying to get rows of three to sit side by side, equal distance apart. I've managed this with the rule

justify-content:space-around

but my problem is that when there is more than three items, the next row starts filling up from the centre, whereas I'd like it to fill up from the left as the user adds more icons over time.

The further I get with explaining this the more unsure I am as to whether this is even possible, but I thought I'd throw it out there just in case.

Is it possible to make the list items in the next row start from the left of the container without messing up the justify-content:space-around rule?

At the moment they only line up when there is three in both rows.

Here's the code

.box {
  width:275px;
  height:275px;
  background-color:yellow;
}

ul { 
  width:auto;
  display:flex;
  flex-direction:row;
  justify-content:space-around;
  flex-wrap: wrap;
  padding: 30px 20px 30px 20px;
  list-style: none; 
}

li {
  width:30px;
  height:30px;
  margin:15px;
  background-color:red;
}
<div class="box">

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>

</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Jack Averill
  • 821
  • 1
  • 10
  • 27

3 Answers3

7

Solution

Instead of justify-content: space-around use justify-content: space-between.


Explanation

Take a look at the flexbox spec:

8.2. Axis Alignment: the justify-content property

The justify-content property aligns flex items along the main axis of the current line of the flex container.

There are five values that apply to justify-content. Here are two of them:

space-around

Flex items are evenly distributed in the line, with half-size spaces on either end.

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

Emphasis mine. That's the problem you're having.

Now check out space-between:

space-between

Flex items are evenly distributed in the line.

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.

So, to left-align your flex item on wrap, use space-between.

Then, if necessary, you can add some left and right padding to the container to simulate space-around.


Of course, the next problem you'll face is when two items wrap, and each item aligns at opposite ends. But that's another question altogether :-)

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 2
    Thanks Michael, I'm not sure what even made me try using `space-around`, it's the first time I've tried it actually. I've used `space-between` before a few times but it didn't even occur to me to try it here as for some reason I thought it would have a similar effect to `space-around`. Your answer is really clear and a perfect solution to my problem :) – Jack Averill Apr 07 '16 at 22:11
0

Not possible with native flexbox...or any other layout methods for that matter. There are workarounds but without those..not really.

However, if the number of possible extra left-over items is known (in this case 2) you can add hidden items to even things out...see I said it was hacky.

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.box {
  width: 275px;
  height: 175px;
  background-color: yellow;
}
ul {
  width: auto;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  flex-wrap: wrap;
  padding: 30px 20px 30px 20px;
  list-style: none;
}
li {
  width: 30px;
  height: 30px;
  margin: 15px;
  background-color: red;
}
.hidden {
  opacity: 0;
  height: 0;
}
<div class="box">

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li class="hidden"></li>
    <li class="hidden"></li>
  </ul>

</div>

<div class="box">

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li class="hidden"></li>
    <li class="hidden"></li>
  </ul>

</div>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • Hi Paulie, maybe I'm misunderstanding these similar questions, but my answer above seems to work. And my answer to this more recent post may be a solution, as well. http://stackoverflow.com/q/38290861/3597276 – Michael Benjamin Jul 10 '16 at 13:39
  • I'm not saying it can't be done **with hacks** but it's not *native* to flexbox. That's my point. – Paulie_D Jul 10 '16 at 15:22
  • But that's my point, as well. The behavior is defined in the spec. It's not a hack. – Michael Benjamin Jul 10 '16 at 15:43
-2

Remove the margins on the li tag.

Also don't forget that ul and li have default styles applied by the browser. Consider using a css reset to have consistency across all browsers.

  • Hmm, thanks I hadn't heard of that. I'll try adding it to my stylesheet as I've often wondered why things have margin values etc when I haven't specified any myself. As for the margins on the li tags, I need them to keep some space between the rows when there are more than three list items. – Jack Averill Apr 07 '16 at 21:41
  • Removing margins from the `li` tag will just create more space around the boxes which might take the 4th box on the first line. Nothing else. – Roy Apr 07 '16 at 21:45