Search code examples
javascripthtmlcsscss-positionsticky

Navigation bar : position Absolute and Sticky


I'm trying to make a navigation bar that overlap my header and stick to the top of the window on scroll.
It will start at top: 45px and stick at top: 0 on scroll.

My first approach was to set it at position: fixed; top: 45px and change the value with JS on a scroll event. But Firefox gave me the warning about "asynchronous panning" discussed on this post.

I have been able to do it with a bit of CSS trickery, but I am wondering if there is a simpler CSS way or a valid JS approach to do this (not throwing a warning).

body {
  position: relative;
  height: 100%;
  width: 100%;
  background-color: grey;
  overflow-x: hidden;
  margin: 0;
}

.container {
  position: absolute;
  top: 0;
  left: -1px;
  width: 1px;
  bottom: 0;
  padding-top: 45px;
  overflow: visible;
}

nav {
  position: sticky;
  top: 0;
  transform: translateX(-50%);
  margin-left: 50vw;
  width: 300px;
  height: 70px;
  background-color: red;
}

header {
  height: 50vh;
  background-color: blue;
}

main {
  height: 200vh;
  width: 100%;
  background-color: green;
}
<div class="container">
  <nav></nav>
</div>
<header>
</header>
<main>
</main>


Solution

  • You can simplify your code and avoid using an extra container:

    body {
      background-color: grey;
      margin: 0;
    }
    
    nav {
      position: sticky;
      top: 0;
      width: 300px;
      height: 70px;
      margin:45px auto -115px; /* 115 = height + margin-top */
      background-color: red;
    }
    
    header {
      height: 50vh;
      background-color: blue;
    }
    
    main {
      height: 200vh;
      background-color: green;
    }
    <nav></nav>
    <header>
    </header>
    <main>
    </main>