1

I am creating simple navigation with flexbox CSS3 and I have a list with 3 items but those items have not specified width. Now I want to have the middle item to be placed in the center of the viewport. When I have that kind of situation my middle li is not centered on the viewport. Is there any way to center one item and other elements to be relative to this item?

See the differences between first and second navigation. On second navigation when there is one item it's properly centered to the viewport. I want to center the first one like second. Li element with class middle must be at the center of the viewport.

EDIT

Some of the answers did the typical moving first and last LI to the edges of the UL LIST. That's not the point, MIDDLE li must be at the center of the viewport and first and last LI should have only paddings and width: initial

ANSWER

I cannot add answer here so I paste 'codepen' link with answer which I want to get

https://codepen.io/freestyle09/pen/xxxvwPm

UPDATED CODE

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
nav {
  border: 1px solid red;
  display: flex;
  justify-content: center;
}

ul {
  display: flex;
  justify-content: center;
  list-style: none;
  border: 1px solid green;
  width: 1200px;
}
ul > li {
  padding: 20px;
  white-space: nowrap;
  border: 1px solid blue;
}
li:not(.middle) {
  flex-basis: 0%;
  flex-grow: 1;
}

nav .test {
  display: flex;
  justify-content: center;
  width: 800px;
  border: 2px solid pink;
  padding: 20px
}
<nav>
  <ul>
        <li><span>Lorem ipsum sit</span></li>
    <li><span>Lorem ipsum sit</span></li>
    <li class='middle'><span>Vey long string, very very very long string</span></li>
    <li><span>About</span></li>
       <li><span>About</span></li>
  </ul>
</nav>
<nav>
  <div class='test'>
    <p>Vey long string, very very very long string</p>
  </div>
</nav>
Freestyle09
  • 4,894
  • 8
  • 52
  • 83

3 Answers3

1

I'm not entirely sure I understand what you're trying to accomplish but this sounds like maybe what you're after?

Addendum, you just described the purpose of a table for tabular data. Hope this helps, cheers!

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

nav {
  border: 1px solid red;
}

ul {
  display: table;
  width: 100%;
  list-style: none;
  align-items: center;
  border: orange 3px dashed;
}

ul > li {
  display: table-cell;
  text-align: center;
  padding: 20px;
  border: green 1px dotted;
}

ul > li:nth-child(odd) {
  width: 20%;
}
<nav>
  <ul>
    <li>Lorem ipsum sit</li>
    <li class='middle'>Vey long string, very very very long string</li>
    <li>About</li>
  </ul>
</nav>
<nav>
  <ul>
    <li>Vey long string, very very very long string</li>
  </ul>
</nav>
Chris W.
  • 22,835
  • 3
  • 60
  • 94
  • This very long string must be in the same position in first and second navigation. Second navigation is centered to the viewport, on first navigation those li elements are moving my MIDDLE li to the right, do you see this? – Freestyle09 Nov 27 '19 at 15:30
  • @Freestyle09 see updated answer. – Chris W. Nov 27 '19 at 15:39
  • The problem with this approach is that the first LI element has e.g. 10px to the right edge and 'ABOUT' LI has got 20px to the left edge, I need to be this dynamic. I know this is a hard question but I need this :/ – Freestyle09 Nov 27 '19 at 15:42
1

On way to approach this is to give the li.middle element a higher flex-grow priority and a lower flex-shrink priority than the other li elements.

The style flex is a shorthand for:

  • flex-grow
  • flex-shrink
  • flex-basis

It will take flex values such as these:

flex: 1 1 20%; // flex-grow priority of 1, flex-shrink priority of 1, pre-flex starting width of 20%
flex: 2 0 60%; // flex-grow priority of 2, will never shrink, pre-flex starting width of 60%

Using these two values above we can declare that:

  • one class of element has a default width of 20% and can both grow and shrink to fill the width available
  • another class of element has a default width of 60%, is twice as likely to grow wider than the other elements, but can never shrink to less than 60%

Working Example:

nav {
  border: 1px solid red;
}
ul {
  display: flex;
  list-style: none;
  justify-content: center;
  border: 1px solid green;
  margin-left: 0;
  padding-left: 0;
}

ul > li {
  padding: 20px;
}

li {
border: 1px solid blue;
}

li {
  flex: 1 1 20%;
}

li.middle {
  flex: 2 0 60%;
  text-align: center;
}
<nav>
<ul>
<li>Lorem ipsum sit</li>
<li class="middle">Very long string, very very very long string</li>
<li>About</li>
</ul>
</nav>

<nav>
<ul>
<li class="middle">Very long string, very very very long string</li>
</ul>
</nav>
Rounin
  • 27,134
  • 9
  • 83
  • 108
0

Adding the following properties to your style should fix your problem.

ul > li {
    padding: 20px;
    flex: 1;
    text-align: center;
}

That will set all the li element sizes to be equal and align their text to the center of it.

CeesJanNolen
  • 76
  • 1
  • 7