No Time Dad

A blog about web development written by a busy dad

Active Nav Link Example

I was browsing online looking for some design inspiration and I found myself on the Ether Cards website. I’d heard about them from a podcast where the host mentioned they had a nice looking site.

I don’t have any interest in Ethereum, playing cards, or Ethereum playing cards, but I was interested to see if the site was as nice as the podcast host described. It’s not the fanciest site I’ve come across, but I like the look of it and it’s designed in a way that fits well within the crypto world. Dark and mysterious.

Of all of the fancy elements on this site, the nav links on the top toolbar caught my attention. I noticed that the active link on the toolbar had a bottom border which sat on the edge of the toolbar itself. At least it appeared to be there anyways.

eth_header

I realize this is strange thing to be interested in, but I’ve always seen active link underlines or styles closer to the text itself. I was curious how they were pushing it down so far and still kept the the text centered. Maybe some trickery with bottom margins was my initial thought. But, I was wrong.

Initial attempt

Below is a stripped down version what my naive first approach would look like. This isn’t really bad, but clearly the bottom border is directly under the text instead of on the edge of the toolbar container

<div class="Base__Nav">
  <nav>
    <a class="Nav__Item Nav__Item__Active" href="#link1">Home</a>
    <a class="Nav__Item" href="#link2">About</a>
    <a class="Nav__Item" href="#link3">Contact</a>
  </nav>
</div>
.Base__Nav {
  color: lightgoldenrodyellow;
  background-color: darkslategray;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.Nav__Item {
  text-decoration: none;
  color: lightgoldenrodyellow;
}

nav > .Nav__Item:not(:last-child) {
  margin-right: 1rem;
}

.Nav__Item__Active {
  border-bottom: 2px solid lightgoldenrodyellow;
}

Stumbling onto a solution

My first solution failed, so I decided to bite the bullet and look at the source code for the Ether Cards site. It turned out that their nav was actually a unordered list of links. Each anchor link was inside of a li element.

Using the li element I can control the height independent of the anchor link. I just needed a way to force the li element to take up the entire height of the parent Base__Nav div.

What I ended up doing was cascading down height: 100% from the nav element to the unordered list ul element, and finally down to the li element. This ensured that the li element’s height would take up all of the available space.

After the li element spans the entire height of the parent, all I had to do was add the active link style I used previously for the bottom border to it. Which is great news because I secretly hoping to avoid guessing at element heights. Using height: 100%; is more reliable, especially as I add more content to the toolbar itself.

Final code and demo

Below is the final code and demo for the border bottom active nav link.

<div class="Base__Nav">
  <nav class="Nav__Container">
    <ul class="Nav__List">
      <li class="Nav__Item__Active">
        <a class="Nav__Item" href="#link1">Home</a>
      </li>
      <li>
        <a class="styles.Nav__Item" href="#link2">About</a>
      </li>
      <li>
        <a class="Nav__Item" href="#link3">Contact</a>
      </li>
    </ul>
  </nav>
</div>
.Base__Nav {
  color: lightgoldenrodyellow;
  background-color: darkslategray;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.Nav__Container {
  height: 100%;
}

.Nav__List {
  display: flex;
  align-items: center;
  margin: 0;
  height: 100%;
}

.Nav__List > li:not(:last-child) {
  margin-right: 1rem;
}

.Nav__Container > ul {
  height: 100%;
}

.Nav__Container > ul > li {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.Nav__Item {
  text-decoration: none;
  color: lightgoldenrodyellow;
}

.Nav__Item__Active {
  border-bottom: 2px solid lightgoldenrodyellow;
}

Conclusion

Sometimes, html and css are funny. This random design from a random website that seemed so innocuous turned out to be pretty tricky to implement. I can understand why some people get discouraged when trying to write html and css. I think implementing this would be difficult for a newcomer.

Like with anything, though, learning to work through and tackle edge cases like this will make you a better developer.