DEV Community

Nic
Nic

Posted on • Originally published at blog.nicm42.me.uk

Navigation underline animation

I recently had a design with three tabs and an underline that indicated which was active. I've seen an animation where the line moves between the tabs, but hadn't used it before. So I decided to try it this time. And it turns out to be simple.

For this I've used a navigation rather than tabs, to keep it simple.

The setup

This is just to get the elements in there and centred. Note: it's important that the navigation links are all the same width and have no gap between them.

HTML

<nav>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
    <li class="line"></li>
  </ul>
</nav>
Enter fullscreen mode Exit fullscreen mode

CSS

nav {
  display: flex;
  justify-content: center;
}

ul {
  display: inline-flex;
  justify-content: center;
  list-style-type: none;
  position: relative;
}

li:not(.line) {
  width: 100px;
}
Enter fullscreen mode Exit fullscreen mode

The line

Our underline here is .line. We're going to absolutely position it below the navigation elements.

.line {
  position: absolute;
  bottom: -8px;
  left: 0;
  width: 33%;
  height: 2px;
  background-color: black;
  transition: left .3s ease;
}
Enter fullscreen mode Exit fullscreen mode

We're transition the left attribute because what we'll do is to move it left based on which link is being hovered/focused.

Since .link is a part of the unordered list, the simplest way to do this is to look at when the lis themselves are being hovered or when their containing link is being focused. This layout is very simple, so it doesn't matter, but on something more interesting it means that the link and the li both have to be the same width and height.

li:first-child:hover ~ .line,
li:first-child:focus-within ~ .line {
  left: 0;
}

li:nth-child(2):hover ~ .line,
li:nth-child(2):focus-within ~ .line {
  left: 33%;
}

li:nth-child(3):hover ~ .line,
li:nth-child(3):focus-within ~ .line {
  left: 67%;
}
Enter fullscreen mode Exit fullscreen mode

And that's all it takes! Although obviously if you were to add a link you'd need to change this to move the left position a quarter of the way across per link.

The final code

Top comments (0)