useSticky
React Hook that tracks element sticky
useSticky detects whether an element has scrolled past a threshold and should become “sticky.” It works by observing the scroll position of a container (or the window) relative to a guard element and returns a tuple of [isSticky, setIsSticky]. You configure it with a nav offset (e.g., a fixed header height) and optionally specify the scroll axis (x or y).
When to Use
- Implementing sticky headers, navigation bars, or sidebars that pin after scrolling past a certain point
- Building “back to top” buttons or floating action bars that appear after scrolling
- Creating scroll-aware UI that changes style or behavior based on scroll position relative to a marker element
Notes
- Scroll container: By default, the hook listens to the window scroll. Pass a third
scrollElementref to observe scrolling within a specific container. - Axis support: Set
axis: 'x'in the params to track horizontal scrolling instead of the default vertical ('y'). - See also
useWindowScrollfor tracking the raw scroll position of the window.
Usage
Live Editor
function Demo() { const element = useRef<HTMLDivElement>(null); const [isSticky] = useSticky(element, { // header fixed height nav: 64, }); const stickyStyle: CSSProperties = isSticky ? { position: "fixed", top: 64, zIndex: 50, height: 20, } : { height: 20, }; const guardStyle: CSSProperties = { width: 1, height: 1, }; return ( <div style={{height: 300,overflow: 'scroll'}}> <div ref={element} style={guardStyle} /> <button style={stickyStyle}> {isSticky ? "stickying" : "not sticky"} </button> <div style={{ height: "100vh" }} /> </div> ); };
Result
API
useSticky
Returns
[boolean, React.Dispatch<React.SetStateAction<boolean>>]: A tuple with the following elements:
- The current state of sticky.
- A function to update the value of sticky.
Arguments
| Argument | Description | Type | DefaultValue |
|---|---|---|---|
| targetElement | dom element | BasicTarget<HTMLElement> (Required) | - |
| params | optional params | UseStickyParams (Required) | - |
| scrollElement | scroll container | BasicTarget<HTMLElement> | - |
UseStickyParams
| Property | Description | Type | DefaultValue |
|---|---|---|---|
| axis | axis of scroll | 'x' | 'y' | y |
| nav | cover height or width | number (Required) | 0 |
BasicTarget
export type BasicTarget<T extends TargetType = Element> = (() => TargetValue<T>) | TargetValue<T> | MutableRefObject<TargetValue<T>>;
TargetValue
type TargetValue<T> = T | undefined | null;
TargetType
type TargetType = HTMLElement | Element | Window | Document | EventTarget;