Detect when an Element Gets Fixed in CSS position:sticky using Intersection Observer

The CSS position: sticky property allows elements to stick to a specific position when scrolling. To detect when a sticky element becomes fixed, we use the Intersection Observer API to monitor a reference element above the sticky element.

Syntax

.sticky-element {
    position: sticky;
    top: 0;
}

How Intersection Observer Detects Sticky States

The Intersection Observer monitors when a reference element (placed just above the sticky element) enters or exits the viewport. When the reference element disappears from view, the sticky element becomes fixed.

HTML Structure

Create the required HTML structure with a reference element and sticky container −

<div id="spacer"></div>
<div id="navbar-top"></div>
<div id="container">Watch Me!</div>
<div id="content"></div>

CSS Styling

Style the sticky element and define the visual changes when it becomes fixed −

#navbar-top {
    background-color: lightgrey;
    height: 2px;
}

#container {
    position: sticky;
    top: 0;
    background-color: #f0f0f0;
    height: 55px;
    text-align: center;
    font-size: 24px;
    line-height: 55px;
    font-weight: bold;
    transition: all 0.3s ease;
}

.sticky-fixed {
    background-color: orange;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);
    font-size: 20px;
}

JavaScript Implementation

Use the Intersection Observer API to detect when the sticky element becomes fixed −

let observer = new IntersectionObserver(function(entries) {
    if(entries[0].intersectionRatio === 0) {
        document.querySelector("#container").classList.add("sticky-fixed");
    } else if(entries[0].intersectionRatio === 1) {
        document.querySelector("#container").classList.remove("sticky-fixed");
    }
}, { threshold: [0, 1] });

observer.observe(document.querySelector("#navbar-top"));

Complete Example

Here's a working example that detects when the sticky element becomes fixed and applies visual changes −

<!DOCTYPE html>
<html>
<head>
<style>
    body {
        margin: 0;
        font-family: Arial, sans-serif;
    }
    
    #spacer {
        background-color: lightblue;
        height: 200px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 18px;
    }
    
    #navbar-top {
        background-color: transparent;
        height: 1px;
    }
    
    #container {
        position: sticky;
        top: 0;
        background-color: #f0f0f0;
        height: 60px;
        text-align: center;
        font-size: 24px;
        line-height: 60px;
        font-weight: bold;
        transition: all 0.3s ease;
        border: 2px solid #ddd;
    }
    
    .sticky-fixed {
        background-color: orange;
        box-shadow: 0 4px 15px rgba(0,0,0,0.2);
        font-size: 20px;
        color: white;
    }
    
    #content {
        background: linear-gradient(45deg, #e3f2fd, #bbdefb);
        height: 1500px;
        padding: 20px;
        font-size: 18px;
    }
</style>
</head>
<body>
    <div id="spacer">Scroll down to see the sticky effect</div>
    <div id="navbar-top"></div>
    <div id="container">Watch Me Stick!</div>
    <div id="content">
        <h3>Content Area</h3>
        <p>Keep scrolling to see how the sticky element changes when it becomes fixed to the top of the viewport.</p>
        <p>The Intersection Observer API monitors the reference element above the sticky container.</p>
    </div>
    
    <script>
        let observer = new IntersectionObserver(function(entries) {
            if(entries[0].intersectionRatio === 0) {
                document.querySelector("#container").classList.add("sticky-fixed");
            } else if(entries[0].intersectionRatio === 1) {
                document.querySelector("#container").classList.remove("sticky-fixed");
            }
        }, { threshold: [0, 1] });
        
        observer.observe(document.querySelector("#navbar-top"));
    </script>
</body>
</html>
A page with a blue header section and a sticky navigation bar that changes from gray to orange with a shadow when it becomes fixed at the top during scrolling. The text "Watch Me Stick!" also becomes white when fixed.

Conclusion

Using the Intersection Observer API with a reference element provides an efficient way to detect when sticky elements become fixed. This technique allows you to apply visual feedback and enhance the user experience during scrolling.

Updated on: 2026-03-15T15:32:35+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements