2

I have the following code snippet (only HTML and CSS)

.container {
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
}

nav ul {
  display: flex;
  flex-direction: row;
  justify-content: center;
  padding: 0;
}

nav ul li {
  list-style: none;
  padding: 0 5px;
}
<div class="container">
  <nav class="menu1">
    <ul>
      <li>1.1</li>
      <li>1.2</li>
    </ul>
  </nav>

  <nav class="menu2">
    <ul>
      <li>2.1</li>
      <li>2.2</li>
      <li>2.3</li>
      <li>2.4</li>
      <li>2.5</li>
      <li>2.6</li>
      <li>2.7</li>
      <li>2.8</li>
      <li>2.9</li>
    </ul>
  </nav>

  <nav class="menu3">
    <ul>
      <li>3.1</li>
      <li>3.2</li>
      <li>3.3</li>
      <li>3.4</li>
      <li>3.5</li>
      <li>3.6</li>
      <li>3.7</li>
      <li>3.8</li>
      <li>3.9</li>
    </ul>
  </nav>
</div>

As you notice, the middle menu (the nav with class .menu2) is equally spaced between .menu1 and .menu3 because of the CSS property justify-content: space-between; in .container. This is correct.

What I need however, is to make sure that .menu2 is in the center of .container. In other words, it will NOT be equally spaced between .menu1 and .menu3. I want it dead center inside .container (and do not worry about menu items overlapping; I will have less menu items in each menu, so they will not overlap. I just added a lot of them here to demonstrate the spacing issue). Also, .menu1 should be also left aligned, and .menu3 should be right aligned (as they are right now).

How do I do that?

Thanks.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Greeso
  • 7,544
  • 9
  • 51
  • 77

4 Answers4

2

it seems like a grid would be better than a flex in my opinion. you can then change the initial and last ul to display: inline-flex then, for the last ul to be aligned to the end, you add to its nav element (class='menu3') a property text-align=end

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  border: 1px solid black;
}

nav ul {
  display: flex;
  flex-direction: row;
  justify-content: center;
  padding: 0;
}

.menu1 ul{
    display: inline-flex;
}

.menu3{
    text-align: end;
}
.menu3 ul{
    display: inline-flex;
}

nav ul li {
  list-style: none;
  padding: 0 5px;
}

looks like this

1

Do you have to use flex? Otherwise it is possible to move menu 2 to the center with position absolute.

.container {
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
  position: relative;
}

nav ul {
  display: flex;
  flex-direction: row;
  justify-content: center;
  padding: 0;
}

nav ul li {
  list-style: none;
  padding: 0 5px;
}

.menu2 {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
<html>

<body>

  <div class="container">
    <nav class="menu1">
      <ul>
        <li>1.1</li>
        <li>1.2</li>
      </ul>
    </nav>

    <nav class="menu2">
      <ul>
        <li>2.1</li>
        <li>2.2</li>
        <li>2.3</li>
        <li>2.4</li>
        <li>2.5</li>
        <li>2.6</li>
        <li>2.7</li>
        <li>2.8</li>
        <li>2.9</li>
      </ul>
    </nav>

    <nav class="menu3">
      <ul>
        <li>3.1</li>
        <li>3.2</li>
        <li>3.3</li>
        <li>3.4</li>
        <li>3.5</li>
        <li>3.6</li>
        <li>3.7</li>
        <li>3.8</li>
        <li>3.9</li>
      </ul>
    </nav>
  </div>

</body>

</html>
Chris Li
  • 2,628
  • 1
  • 8
  • 23
  • This is the best way imo. There isn't a way (as far as I know) to avoid the box dimensions of an element, as OP mentioned by "ignoring the overlapping." So just setting the middle element absolutely, and either doing margin-left: auto and margin-right: auto respectively, should absolutely center the element. – alex067 Mar 04 '20 at 19:57
0

I know it is not Flexbox but you may want to look at CSS grid-layout.

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  border: 1px solid black;
}

nav ul {
  padding: 0;
}

nav ul li {
  display: inline-block;
  list-style: none;
  padding: 0 5px;
}
<html>

<body>

  <div class="container">
    <nav class="menu1">
      <ul>
        <li>1.1</li>
        <li>1.2</li>
      </ul>
    </nav>

    <nav class="menu2">
      <ul>
        <li>2.1</li>
        <li>2.2</li>
        <li>2.3</li>
        <li>2.5</li>
        <li>2.9</li>
      </ul>
    </nav>

    <nav class="menu3">
      <ul>
        <li>3.1</li>
        <li>3.2</li>
        <li>3.3</li>
        <li>3.4</li>
        <li>3.5</li>
        <li>3.6</li>
        <li>3.7</li>
        <li>3.8</li>
        <li>3.9</li>
      </ul>
    </nav>
  </div>

</body>

</html>
line-o
  • 1,885
  • 3
  • 16
  • 33
0

I would set the .menu1-3 to different flex rules, having those on the outside trying to talk equally much of the space while the one in the middle takes just what it needs.

The overflow: hidden is important to make sure content doesnt over-span the flex-base. But there are other rules with same effect depending on what behaviour of the items you want (like flex-wrap to wrap the items to the next line)

Depending on what you want you can consider giving the middle column a specific flex-base like fixed pixel or percentage (like all 3 .menu get 33.33%). Add margin (to middle column) as well if needed.

The solution with grid and the absolute positions might also do the job depending on that you want. Position: absolute has the best browser support, my flex solution works on most browsers these days. Grid also should but has the worst coverage as far as i know

.container {
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
}

nav ul {
  display: flex;
  flex-direction: row;
  justify-content: center;
  padding: 0;
}

nav ul li {
  list-style: none;
  padding: 0 5px;
}

.menu1, .menu3 {
  flex: 1 1 50%;
overflow: hidden;  
}

.menu1 ul {
justify-content: flex-start
}
.menu2 ul {
justify-content: flex-end
}

.menu2 {
  flex: 0 0 auto;
}
<html>

<body>

  <div class="container">
    <nav class="menu1">
      <ul>
        <li>1.1</li>
        <li>1.2</li>
      </ul>
    </nav>

    <nav class="menu2">
      <ul>
        <li>2.1</li>
        <li>2.2</li>
        <li>2.3</li>
        <li>2.4</li>
        <li>2.5</li>
        <li>2.6</li>
        <li>2.7</li>
        <li>2.8</li>
        <li>2.9</li>
      </ul>
    </nav>

    <nav class="menu3">
      <ul>
        <li>3.1</li>
        <li>3.2</li>
        <li>3.3</li>
        <li>3.4</li>
        <li>3.5</li>
        <li>3.6</li>
        <li>3.7</li>
        <li>3.8</li>
        <li>3.9</li>
      </ul>
    </nav>
  </div>

</body>

</html>
user6292372
  • 228
  • 1
  • 7