Setting margin to auto in a flexbox

Viewed 71

I was following along the tutorial on youtube link and I got stuck in this part that's using margin-top: auto in a flexbox to push the last child to bottom. Can you please point out what's not working here?

.navbar {
    width: 5rem;
    height: 100vh;
    position: fixed;
    background-color: var(--bg-primary);
}

.navbar-nav {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.nav-item:last-child {
    margin-top: auto;
}
<nav class="navbar">

      <ul class="navbar-nav">

        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>

      </ul>

</nav>

3 Answers

you should add height: 100%; either

.navbar {
    width: 5rem;
    height: 100%;
    position: fixed;
    background-color: var(--bg-primary);
}

.navbar-nav {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    height:100%;
}

.nav-item:last-child {
    margin-top: auto;
}
<nav class="navbar">

      <ul class="navbar-nav">

        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>

      </ul>

</nav>

This works as expected, the last <li> is pushed to the bottom of the parent, but since the parent (.navbar-nav) has the same height, you don't see the element moving.

Increasing the .navbar-nav height will enable the <li> to move down:

.navbar-nav {
    ...
    height: 100vh;
}

.navbar {
    width: 5rem;
    height: 100vh;
    position: fixed;
    background-color: var(--bg-primary);
}

.navbar-nav {
    height: 100vh;
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.nav-item:last-child {
    margin-top: auto;
}
<nav class="navbar">

      <ul class="navbar-nav">

        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>

      </ul>

</nav>

After setting the height of 100vh to .navbar-nav, you can use flex:1 on 2nd child to make sure it takes the free space around. This will automatically push the last child to the bottom. In this case you even don't need to bother about using margin's to place elements inside the flex-container at different positions. flexbox properties and flex-item properties takes care of positioning our flex-items.

Code Modifications:

.navbar-nav{
  height:100vh;
 }
.nav-item:nth-child(2) {
    flex:1;
}

.navbar {
    width: 5rem;
    height: 100vh;
    position: fixed;
    background-color: teal;
    
}

.navbar-nav {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    height:98vh;
}

.nav-item:nth-child(2) {
    flex:1;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<nav class="navbar">

      <ul class="navbar-nav">

        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="" >
            <span class="link-text">Cats</span>
          </a>
        </li>

      </ul>

</nav>
</body>
</html>

Note: The fundamental issue with margin-top not working is already covered in the above answers. Obviously the height issue with flex-container .navbar-nav div

Related