2

I have a nav which has a number of menu items. The text in each menu item varies in length.

Here's how it's looking:

nav ul {
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-align: center;
  margin: 0;
  padding: 0;
}

nav ul li {
  background: darkblue;
  list-style: none;
  padding: 24px;
}

a {
  color: #fff;
  text-decoration: none;
}
<nav>
  <ul>
    <li><a href="#">Menu Item</a></li>
    <li><a href="#">A Longer Menu Item</a></li>
    <li><a href="#">A Very Very Long Menu Item</a></li>
    <li><a href="#">Menu Item</a></li>
  </ul>
</nav>

The problem here is that it leaves large gaps between each item when viewport is wide. To fix this, I've added width: 100%; to the <li>, like so:

nav ul {
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-align: center;
  margin: 0;
  padding: 0;
}

nav ul li {
  width: 100%;
  border-right: 3px solid #fff;
  background: darkblue;
  list-style: none;
  padding: 24px;
}

a {
  color: #fff;
  text-decoration: none;
}
<nav>
  <ul>
    <li><a href="#">Menu Item</a></li>
    <li><a href="#">A Longer Menu Item</a></li>
    <li><a href="#">A Very Very Long Menu Item</a></li>
    <li><a href="#">Menu Item</a></li>
  </ul>
</nav>

This kind of solves the problem, but now the heights are not equal. Is there a way within flexbox to fix this?

Sam
  • 1,401
  • 3
  • 26
  • 53
  • 1
    Add `flex: 1 1 auto` to the `li` instead of the width property. – disinfor Sep 16 '19 at 19:24
  • Simply use `align-items: stretch;` on the `ul`. If you want the `li`'s content to be centered vertically (although I'd say it looks better top aligned), use `display:flex;align-items: center;justify-content: center;` on them. Also, I'd move the background on `ul` from `li`s. – tao Sep 16 '19 at 19:35

1 Answers1

2

You are applying the flex alignment properties to the flex items (the children of the container), not to the content inside the flex items (the grandchildren of the container). That's why you're seeing the items vertically centered (i.e., losing equal height).

Essentially, there are three levels to the HTML structure. So, make the items into flex containers. Now flex properties apply to the content. Here's a more complete explanation: Centering in CSS Grid

Also, since you're using the HTML5, semantically-meaningful <nav> element, there's really no need to also use an unordered list (<ul> / <li>). It's unnecessary and semantically meaningless code.

nav {
  display: flex;
}

a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: darkblue;
  color: #fff;
  text-decoration: none;
}

a + a {
  border-left: 2px solid gray;
}

@media ( max-width: 600px ) {
  nav {
    flex-wrap: wrap;
  }
  a {
    flex-basis: 100%;
  }
  a + a {
    border-left: none;
    border-top: 2px solid gray;
  }
}
<nav>
  <a href="#">Menu Item</a>
  <a href="#">A Longer Menu Item</a>
  <a href="#">A Very Very Long Menu Item</a>
  <a href="#">Menu Item</a>
</nav>

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Thank you. It's been a long day and I think my messy markup wasn't helping me solve this. Great answer. Time to sleep! – Sam Sep 16 '19 at 19:41