How to Hide/Reveal a Sticky Bottom Nav Bar on Scroll (With JavaScript)

If you’ve ever used LinkedIn’s mobile app, you’ve probably noticed the sticky bottom navigation bar. By default, it appears, then as you scroll down disappears, and appears again as you scroll up. 

LinkedIn's Mobile App LayoutLinkedIn's Mobile App LayoutLinkedIn's Mobile App Layout
LinkedIn’s Mobile App Layout

Fixed/sticky navigation bars are the primary layout pattern on mobile apps. 

Udemy's Mobile App LayoutUdemy's Mobile App LayoutUdemy's Mobile App Layout
Udemy’s Mobile App Layout

But nothing stops us from following this pattern for structuring navigation bars on sites in mobile view, either for the primary or the secondary navigation.

In the past, we’ve built something similar to LinkedIn’s app navigation bar—a page header that disappears when scrolling down the page and reveals when scrolling up.

Let’s rely on the core principles of this tutorial and create an app-like bottom navigation bar whose visibility will depend on the scrolling direction, just like the LinkedIn app.

What We’re Building

A picture (demo) is worth a thousand words, so take a look at what we’re going to create (scroll to test the behavior):

For a better experience, be sure to examine it from a mobile device. In a real scenario, there will be two different navigation menus: one for the desktop that will probably sit on the page top and one for the mobile like we have here.

1. Begin With the Page Markup

The markup will consist of the nav element and the main element where we’ll put the page content. Inside the nav, we’ll place our menu which will include five items. Each of them will have an SVG taken from the popular iconmonstr library. To indicate the active page, we’ll add to the associated item the active class. By default, the first item will have this class. Finally, we’ll add a heading that will be visible only on screen readers.

Here’s the page markup:

1
<nav class="nav-mobile">
2
  <h2 class="screen-reader-text">Mobile Menu Navigation Bar</h2>
3
  <ul>
4
    <li class="active">
5
      <a href="">
6
        <svg width="24" height="24" xmlns="https://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd">
7
          <path d="M22 11.414v12.586h-20v-12.586l-1.293 1.293-.707-.707 12-12 12 12-.707.707-1.293-1.293zm-6 11.586h5v-12.586l-9-9-9 9v12.586h5v-9h8v9zm-1-7.889h-6v7.778h6v-7.778z" />
8
        </svg>
9
        Home
10
      </a>
11
    </li>
12
    <li>
13
      <a href="">
14
        <svg width="24" height="24" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
15
          <path d="m7.234 3.004c-2.652 0-5.234 1.829-5.234 5.177 0 3.725 4.345 7.727 9.303 12.54.194.189.446.283.697.283s.503-.094.697-.283c4.977-4.831 9.303-8.814 9.303-12.54 0-3.353-2.58-5.168-5.229-5.168-1.836 0-3.646.866-4.771 2.554-1.13-1.696-2.935-2.563-4.766-2.563zm0 1.5c1.99.001 3.202 1.353 4.155 2.7.14.198.368.316.611.317.243 0 .471-.117.612-.314.955-1.339 2.19-2.694 4.159-2.694 1.796 0 3.729 1.148 3.729 3.668 0 2.671-2.881 5.673-8.5 11.127-5.454-5.285-8.5-8.389-8.5-11.127 0-1.125.389-2.069 1.124-2.727.673-.604 1.625-.95 2.61-.95z" fill-rule="nonzero" />
16
        </svg>
17
        Favorites
18
      </a>
19
    </li>
20
    <!-- three more items here -->
21
  </ul>
22
</nav>
23

24
<main>
25
  <div class="container">...</div>
26
</main>

2. Add the Sticky Nav CSS

Let’s now focus only on the core styles—you can always look at all by clicking on the CSS tab of the demo project.

  • The nav will be a fixed-positioned element sitting at the page bottom.
  • All items will be flex items and occupy the same amount of space across the menu. To ensure this, we’ll manipulate the links’ font size depending on the screen size.
  • To distinguish the active item, we’ll change its color to orange and give it a top border with the same color. Plus, we’ll add the same styling to the hovered items.
Our app-like sticky bottom navigation barOur app-like sticky bottom navigation barOur app-like sticky bottom navigation bar
Our app-like sticky bottom navigation bar

Here are the related styles:

1
.nav-mobile {
2
  position: fixed;
3
  bottom: 0;
4
  left: 0;
5
  width: 100%;
6
  background: var(--white);
7
  transition: transform 0.3s;
8
  z-index: 1;
9
  box-shadow: 0 -3px 6px 0 rgba(0, 0, 0, 0.05);
10
}
11

12
.nav-mobile ul {
13
  display: flex;
14
  list-style: none;
15
  padding: 0;
16
  margin: 0;
17
}
18

19
.nav-mobile li {
20
  flex: 1;
21
}
22

23
.nav-mobile a {
24
  display: flex;
25
  flex-direction: column;
26
  align-items: center;
27
  gap: 5px;
28
  padding: 10px;
29
  border-top: 2px solid transparent;
30
  font-size: 16px;
31
  text-decoration: none;
32
  transition: all 0.3s;
33
}
34

35
.nav-mobile a svg {
36
  transition: fill 0.3s;
37
}
38

39
.nav-mobile li.active a,
40
.nav-mobile a:hover {
41
  color: var(--orange);
42
  border-color: currentColor;
43
}
44

45
.nav-mobile li.active svg,
46
.nav-mobile a:hover svg {
47
  fill: var(--orange);
48
}
49

50
@media (max-width: 600px) {
51
  .nav-mobile a {
52
    font-size: 14px;
53
    padding: 5px;
54
  }
55
}
56

57
@media (max-width: 450px) {
58
  .nav-mobile a {
59
    font-size: 12px;
60
  }
61
}

3. Add the JavaScript

As we start scrolling the page, we‘ll check the scrolling direction and implement this functionality:

  • If we scroll down, the body will receive the scroll-down class. At that point, the navigation will smoothly disappear with a slide-out animation.
  • If we scroll up, it’ll receive the scroll-up class. At that point, the navigation will smoothly appear with a slide-in animation.
  • If we scroll to the top of the page, it’ll lose its scroll-up class.

 Here’s the required JavaScript code which as we discussed earlier will come from a previous tutorial:

1
const body = document.body;
2
const scrollUp = "scroll-up";
3
const scrollDown = "scroll-down";
4
let lastScroll = 0;
5

6
window.addEventListener("scroll", () => {
7
  const currentScroll = window.pageYOffset;
8
  if (currentScroll <= 0) {
9
    body.classList.remove(scrollUp);
10
    return;
11
  }
12

13
  if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) {
14
    // down
15
    body.classList.remove(scrollUp);
16
    body.classList.add(scrollDown);
17
  } else if (
18
    currentScroll < lastScroll &&
19
    body.classList.contains(scrollDown)
20
  ) {
21
    // up
22
    body.classList.remove(scrollDown);
23
    body.classList.add(scrollUp);
24
  }
25
  lastScroll = currentScroll;
26
});

And the associated styles:

1
.nav-mobile {
2
  transition: transform 0.3s;
3
}
4

5
.scroll-down .nav-mobile {
6
  transform: translate3d(0, 100%, 0);
7
}
8

9
.scroll-up .nav-mobile {
10
  transform: none;
11
}

Conclusion 

Another scrolling tutorial came to an end, folks! During this exercise, we created an app-like sticky mobile navigation bar and slid it based on the scrolling direction. I hope you enjoyed it as much as I did and found it inspiring!

Once more, here’s our creation:

Lastly, if you need some inspiration for creative header effects on scroll, consider this tutorial.

As always, thanks a lot for reading!