@bramus/sticky-observer
v1.0.0
Published
Observe CSS `position: sticky` elements getting stuck or unstuck
Maintainers
Readme
Sticky Observer
Observe CSS position: sticky elements getting stuck or unstuck.
It implements the "Sticky Events" pattern using sentinels and IntersectionObserver, allowing you to react to changes in the sticky state of an element.
Installation
npm install @bramus/sticky-observerUsage
Basic Usage
- Import
StickyObserverin your project. - Call
StickyObserver.observe()with a CSS selector for the elements you want to watch. - Listen for the
sticky-changeevent on the observer instance.
import { StickyObserver } from '@bramus/sticky-observer';
// Initialize and observe elements matching the selector
const observer = StickyObserver.observe('h2');
// Listen for state changes
observer.addEventListener('sticky-change', (e: Event) => {
const { target, stuck } = e.detail;
console.log(`Element is now ${stuck ? 'stuck' : 'unstuck'}:`, target);
});CSS Requirement
For the observer to work correctly, the parent container of your sticky element must be positioned (e.g., position: relative).
If the parent is statically positioned, StickyObserver will automatically set position: relative on it and log a warning to the console.
API
StickyObserver.observe(selector, options?)
Static method to create a new observer instance.
selector(string): CSS selector for the element(s) to observe.options(StickyObserverOptions): Optional configuration object.
Returns a StickyObserver instance.
Options (StickyObserverOptions)
| Option | Type | Default | Description |
|---|---|---|---|
| debug | boolean | false | If true, shows visual outlines on the target and sentinels, and enables console logging. |
| container | HTMLElement | null | Optional scroll container to use as the IntersectionObserver root. When omitted, it uses the document viewport |
| remainStickyBeyondStickyEdge | boolean | false | If true, the element reports as "stuck" even when it has exited the scrollport beyond its sticky edge (normally it would unstick). |
Events
The StickyObserver instance extends EventTarget and dispatches the following event:
sticky-change
Fired when the sticky state of an observed element changes.
- Event Type:
CustomEvent<StickyChangeDetail> detailproperty:target: TheHTMLElementthat changed state.stuck:booleanindicating if the element is currently stuck.
Instance Methods
disconnect()
Stops observing all elements and disconnects the internal IntersectionObservers.
observer.disconnect();How it works
This library injects two "sentinel" elements into the parent of the sticky element:
- A Top Sentinel placed before the element (at the start of the parent).
- A Bottom Sentinel placed after the element (at the end of the parent).
It uses IntersectionObserver to track when these sentinels intersect with the viewport (or container). Based on the intersection logic, it determines whether the element is currently in a "stuck" state.
Reference: An event for CSS position:sticky
