Transparent header on scroll

I saw a nice effect the other day, on SourceJS. Basically, when you scroll the page at all, the header becomes transparent, but when you hover over it, it becomes opaque again.

Pretty, yet surprisingly easy to do.

Assume your HTML looks something like:

<body>
  <div id="main-menu">
    <!-- this contains the header -->
  </div>
</body>

The trick to getting stuff really smooth, with limited scripting required, is to use CSS transitions. So, instead of manually changing the opacity of the element, we just set/unset a class on the body, and have some CSS rules to set the opacity.

window.addEventListener('scroll', function () {
  document.body.classList[
    window.scrollY > 20 ? 'add': 'remove'
  ]('scrolled');
});

This fires every time there is a scroll event. In my browser, add/removing this class to the classList takes ~0.01ms.

Finally, there is the required CSS.

body.scrolled #main-menu {
  opacity: 0.2;
  transition: opacity .2s;
}
body.scrolled #main-menu:hover {
  opacity: 1.0;
  transition: opacity .2s;
}

That’s all there is to it!

Here’s one I prepared earlier.