6

For an odd number of flex items I want the middle one to be in perfect center and other items just flow around it. The middle item has fixed width, all the rest are fluid and must stick to the middle item so the paddings are fixed.

enter image description here

/* CSS */

.flex-holder {
 display: flex;
 justify-content: center;
}
.middle-item {
 width: 75px;
}
<!-- HTML -->

<ul class="flex-holder">
  <li>Item 1</li>
  <li>Some item</li>
  <li class="middle-item">Middle</li>
  <li>Very long text item</li>
  <li>Test</li>
</ul>

Is it actually possible with flexbox? If no, please suggest another solution.

artemean
  • 805
  • 1
  • 10
  • 24

2 Answers2

3

One solution would be to use position: absolute on middle element and center it with transform: translate() but there will be overflow of elements on small window size which you can fix with media queries.

.flex-holder {
  display: flex;
  justify-content: space-around;
  position: relative;
  list-style: none;
  padding: 0;
}

.middle-item {
  width: 75px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
<ul class="flex-holder">
  <li>Item 1</li>
  <li>Some item</li>
  <li class="middle-item">Middle</li>
  <li>Very long text item</li>
  <li>Test</li>
</ul>

Another solution that will get result close to desired result is to wrap li's left and right of middle li in ul's and set flex: 1 on them so they take equal size and set middle div always in center.

ul, .wrap {
  display: flex;
  justify-content: space-around;
  position: relative;
  list-style: none;
  flex: 1;
  padding: 0;
}
.middle-item {
  width: 75px;
  background: lightblue;
  text-align: center;
}
<ul class="flex-holder">
  <li class="wrap">
    <ul>
      <li>Item 1</li>
      <li>Some item</li>
    </ul>
  </li>
  <li class="middle-item">Middle</li>
  <li class="wrap">
    <ul>
      <li>Very long text item</li>
      <li>Test</li>
    </ul>
  </li>
</ul>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

The simpliest way if the middle-item is in the middle (same number of items at rigth and left):

.flex-holder {
  display: flex;
  justify-content: center;
  list-style: none;
  padding:0;
}
.flex-holder li {
  flex: 1;
  border: 1px solid red;
}
li.middle-item {
  flex: 0 0 100px;
  background-color: #ccc;
}
<ul class="flex-holder">
  <li>Item 1</li>
  <li>Some text</li>
  <li class="middle-item">Middle</li>
  <li>Very long text item bla bla bla bla bla bla.</li>
  <li>Test</li>
</ul>

Also you can force to the middle nesting elements. For example:

body {
    background: url(http://placehold.it/1x200) no-repeat center;
  }
  
  .flex-holder {
    display: flex;
    list-style: none;
    padding: 0;
  }
  
  .flex-holder li {
    display: flex;
    flex: 1;
    border: 1px solid red;
    justify-content: flex-end;
    padding: 0 1em;
  }
  
  .flex-holder li div {
    border: 1px solid green;
    padding: 0 1em;
  }
  
  li.middle-item {
    flex: 0 0 auto;
    background-color: #ccc;
    text-align: center;
    justify-content: center;
  }
  
  li.middle-item ~ li {
    justify-content: flex-start;
  }
<ul class="flex-holder">
  <li>
    <div>Item 1 </div>
    <div> Some item</div>
  </li>
  <li class="middle-item">Middle</li>
  <li>
    <div>
      Very long text item </div>
  </li>
</ul>
  • The distance between all item must be the same. See my image – artemean Sep 29 '16 at 11:19
  • If you say space between the texts I think isn't possible, at least I don't know how you can do that –  Sep 29 '16 at 11:33
  • I edit my second snippet, I think it is pretty close to what you want but maybe when there is not enought space don't work very well –  Sep 29 '16 at 12:16