# useIsStuck

Whether a `position: sticky` element is currently stuck to the top of the viewport. Returns a callback ref for the sticky element.

Reads the element's own CSS `top` and watches it with an IntersectionObserver, so it costs nothing while scrolling and needs no extra markup. `false` on the server and until the element is measured.

## Import

```ts
import { useIsStuck } from '@vincent.ri/react-tils'
// or only this hook
import { useIsStuck } from '@vincent.ri/react-tils/useIsStuck'
```

## Usage

```ts
const [ref, stuck] = useIsStuck<HTMLElement>()
return (
  <header ref={ref} style={{ position: 'sticky', top: 0 }} className={stuck ? 'shadow' : ''}>
    …
  </header>
)
```

## When to use it

Adding a shadow or border to a sticky header only once it sticks, or shrinking a sticky toolbar.

## When not to

The sticky element sticks inside a scroll container rather than the page; this watches the viewport. If you only need the element to stick, CSS `position: sticky` alone is enough.

## API

```ts
function useIsStuck<T extends Element = HTMLElement>(): [(element: T | null) => void, boolean]
```

**Returns** `[ref, stuck]`. Pass `ref` to the sticky element.

## Browser support

Works in all modern browsers.

## Coming from another library?

Other libraries call this `useSticky`, `useStickyFixed`.

---

268 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useIsStuck.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useIsStuck/
Previous: [useInView](https://vincentri.github.io/react-tils/hooks/useInView.md)
Next: [useStickToBottom](https://vincentri.github.io/react-tils/hooks/useStickToBottom.md)
