<div class="topContent">
  Content above our sticky element
</div>
<div id="sentinel"></div>
<header id="header">
  Sticky header
</header>
<div class="pageContent">
  The rest of the page
</div>
html,
body {
  font-family: Arial;
  padding: 0;
  margin: 0;
}

.topContent,
.pageContent,
#header {
  padding: 10px;
}

#header {
  position: sticky;
  top: 0px;
  transition: all 0.2s linear;
}

#header.stuck {
  background-color: red;
  color: white;
  
}

.topContent {
  height: 50px;
  background-color: gray;
}

.pageContent {
  height: 600px;
  background-color: lightgray;
}
const sentinelEl = document.getElementById('sentinel')
const headerEl = document.getElementById('header')
const stuckClass = "stuck"

const handler = (entries) => {
  if (headerEl) {
    if (!entries[0].isIntersecting) {
      headerEl.classList.add(stuckClass)
    } else {
      headerEl.classList.remove(stuckClass)
    }
  }
}

const observer = new window.IntersectionObserver(handler)
observer.observe(sentinelEl)
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.