How To Slide Up a Bar When User Stops Scrolling

Published: Wednesday, July 1, 2020

gif of finished app

Greetings, friends! I was recently given a task to make a popup appear when the user stops scrolling. When I made it, I was surprised on how easy it actually was to implement! Let's dive in!

tip
If you want to see the code immediately, you can clone my git repository to get started right away. If you want to follow along, feel free to continue reading! :)
md
Copied! ⭐️
git clone https://github.com/inspirnathan/javascript-tutorial-slide-up-bar-on-scroll-stop.git

First, let's create an index.html file:

html
Copied! ⭐️
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Slide on Scroll Stop</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="section-1"></div>
  <div class="section-2"></div>
  <div class="section-3"></div>
  <div class="section-4"></div>
  <div class="bar">
    <h3>Surprise! 🎉</h3>
    <p>I am a popup that appears when you stop scrolling.</p>
  </div>
  <script src="main.js"></script>
</body>
</html>

Next, we need to make our style.css file. Let's remove the default margin from the page.

css
Copied! ⭐️
body {
  margin: 0;
}

Set the height of every section to 500px in our demo app to give us room to scroll. I decided to use a CSS attribute selector to apply this style to every element that has a class name that starts with section-. See attribute selectors for more details if you're curious.

css
Copied! ⭐️
div[class^="section-"] {
  height: 500px;
}

Add color to each section, so it's easy to tell when we're scrolling.

css
Copied! ⭐️
.section-1 {
  background-color: skyblue;
}

.section-2 {
  background-color: orangered;
}

.section-3 {
  background-color: mediumseagreen;
}

.section-4 {
  background-color: magenta;
}

Your app should now look very similar to the animation at the top of this post. The last part of the stylesheet is to add the styling for the popup bar that will appear from the bottom of the page.

css
Copied! ⭐️
.bar {
  background-color: white;
  position: fixed;
  height: 5.5rem;
  width: 100%;
  box-shadow: 1px 2px 10px 0 rgba(0, 0, 0, 0.2);
  padding: 1rem;
  visibility: hidden;
  transition: 0.5s;
  bottom: -7.5rem; /* 5.5rem height + 1rem padding-top + 1rem padding-bottom = 7.5rem */
}

.bar-visible {
  visibility: visible;
  transition: 0.5s;
  bottom: 0;
}

The .bar class is set to fixed and initially hidden. We will apply a transition that will last half a second when we add the .bar-visible class. It's important to note that we set bottom to -7.5rem because it's a combination of the height and vertical padding. It will "rise" up to a value of bottom: 0.

Next, let's add our JavaScript file called main.js:

js
Copied! ⭐️
const bar = document.querySelector('.bar')

let timeoutId

function handleScroll() {
  bar.classList.remove('bar-visible')
  clearTimeout(timeoutId)

  timeoutId = setTimeout(() => {
    bar.classList.add('bar-visible')
  }, 500)
}

document.addEventListener('scroll', handleScroll)

We listen to the scroll event and pass in a handleScroll callback that will fire every time the user scrolls. If user does not scroll within 500 milliseconds, then we add the bar-visible class to make the popup appear, which will trigger the transition that is attached to the bar class. If the user starts scrolling, then we will remove the bar-visible class to trigger another transition and call clearTimeout to remove the previous setTimeout. Luckily, calling clearTimeout on undefined results in no JavaScript errors. When the user begins at the top of the page, no scroll event is fired, so we get the added bonus of not showing the popup until the user has scrolled away from the top of the page.

That's it! Super simple! You can find the finished code here.