'How to align one flex child as flex-start and other in center?

I have a sidebar that is set to flex with direction column. I am trying to get my menu ul to be vertically centered, and my .logo-container to be on the top of the page.

Is there any way to get one child to flex-start and another one centered?

Code:

<aside class="side-bar">
    <nav class="navigation">
      <div class="logo-container">
        <a href="index.html" class="link">
          <img src="http://unsplash.it/30/30" class="logoimg" alt="">
          <h6 class="logoname">My<span class="lastname">Name</span></h6>
        </a>
      </div>
      <ul class="nav-list">
        <li class="item"><a href="#" class="link">Menuitem1</a></li>
        <li class="item"><a href="#" class="link">Menuitem2</a></li>
        <li class="item"><a href="#" class="link">Menuitem3</a></li>
        <li class="item"><a href="#" class="link">Menuitem4</a></li>
      </ul>
    </nav>
  </aside>

CSS:

html {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

.side-bar {
  width: 35%;
  height: 100vh;
  background-color: blue;
}

.navigation {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  
  height: 100%;
}

.logoname {
  display: inline-block;
}

* {
  color: black;
}

ul {
  list-style: none;
}

Codepen

Many thanks!



Solution 1:[1]

What you can do is to create an empty/invisible element as a third flex item inside the flex parent (in my example below it's the divwith class xxx) and apply justify-content: space-between to the flex parent (instead of center).

Depending on your actual code and content you should make sure that that additional element has the same height as the nav element (30px in your and my example). And again, depending on the situation you might want to add visibility: hidden; to the additional element (xxx) to make it invisible but still have its height included in the flex position calculations:

html {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

.side-bar {
  width: 35%;
  height: 100vh;
  background-color: blue;
}

.navigation {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  height: 100%;
}

.logoname {
  display: inline-block;
}

* {
  color: black;
}

ul {
  list-style: none;
}

.xxx {
  height: 30px;
  visibility: hidden;
}
<aside class="side-bar">
  <nav class="navigation">
    <div class="logo-container">
      <a href="index.html" class="link">
        <img src="http://unsplash.it/30/30" class="logoimg" alt="">
        <h6 class="logoname">My<span class="lastname">Name</span></h6>
      </a>
    </div>
    <ul class="nav-list">
      <li class="item"><a href="#" class="link">Menuitem1</a></li>
      <li class="item"><a href="#" class="link">Menuitem2</a></li>
      <li class="item"><a href="#" class="link">Menuitem3</a></li>
      <li class="item"><a href="#" class="link">Menuitem4</a></li>
    </ul>
    <div class="xxx"></div>
  </nav>
</aside>

Solution 2:[2]

You can try this approach.

html {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

.side-bar {
  width: 35%;
  height: 100vh;
  background-color: blue;
}

.navigation {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  
  height: 100%;
}



* {
  color: black;
}

ul {
  list-style: none;
}

.logo-container {
  display:grid;
  justify-content:space-around;
  margin:0 auto;
  padding-top: 20px;
  }

.logo-container img {
  text-align:center;
  padding:5px;
  }
 
<aside class="side-bar">
<div class="logo-container">
        <a href="index.html" class="link">
          <img src="http://unsplash.it/30/30" class="logoimg" alt="">
          <h6 class="logoname">My<span class="lastname">Name</span></h6>
        </a>
      </div>
    <nav class="navigation">
      
      <ul class="nav-list">
        <li class="item"><a href="#" class="link">Menuitem1</a></li>
        <li class="item"><a href="#" class="link">Menuitem2</a></li>
        <li class="item"><a href="#" class="link">Menuitem3</a></li>
        <li class="item"><a href="#" class="link">Menuitem4</a></li>
      </ul>
    </nav>
  </aside>

Solution 3:[3]

All you have to do is to have the logo and ul in separate divs within the parent div that has the column direction styling, apply flex-shrink:0 to the div containing the logo and flex-grow: 1 to the other div.

That will allow the logo to be at the top and the other div to take the rest of the space - then you can apply flex styling in the navigation -container to center the ul within that div.

UPDATE - the OP wanted the ul centered into the height of the viewport - as noted in the comments this is as simple as offsetting the position of the ul in the bottom div by half the height of the top div - so in this case - moving it up by 20px) because the top div is 40px in height. This allows centering of the ul into the viewport height without resorting to adding empty divs just to get the alignment.

html {
  box-sizing: border-box;
  color: white;
}

* {
  margin: 0;
  padding: 0;
}

.side-bar {
  width: 35%;
  height: 100vh;
  background-color: blue;
  padding: 8px;
}

.navigation {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
    align-items: center;
}

.logo-container {
 flex-shrink:0
}

.logoname {
  display: inline-block;
  padding : 8px;
    color: lime;
}

.navigation-container {
 flex-grow:1;
   display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

ul {
  list-style: none;
  position: relative;
  top: -20px
}
li a{ color: white; }
<aside class="side-bar">
    <nav class="navigation">
    
      <div class="logo-container">
        <a href="index.html" class="link">
          <img src="http://unsplash.it/30/30" class="logoimg" alt="">
          <h6 class="logoname">My<span class="lastname">Name</span></h6>
        </a>
      </div>
      <div class="navigation-container">
        <ul class="nav-list">
          <li class="item"><a href="#" class="link">Menuitem1</a></li>
          <li class="item"><a href="#" class="link">Menuitem2</a></li>
          <li class="item"><a href="#" class="link">Menuitem3</a></li>
          <li class="item"><a href="#" class="link">Menuitem4</a></li>
        </ul>
      </div>
    </nav>
  </aside>

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Johannes
Solution 2 Crystal
Solution 3