A header that stays at the top as you scroll, and gains an edge once content passes under it.
- Add the registry
- Add sticky-header
Usage
StickyHeader sticks to the top of the nearest container that scrolls, or of the page, or of
the one given as root. It's clear at rest, so it sits on the page like any other header, and
gains a translucent surface and a hairline once the content after it scrolls beneath it, which
data-scrolled marks. Inside a Card the surface takes the card's color. It
takes its top corners from its parent, since browsers don't round a blurred surface by its
container's corners. In a rounded container, give whatever lies between the two
rounded-[inherit], as the example's scroll area has. In a Scroll Area,
turn off scrollFade, or the fade at its top edge covers the header.
It renders a <header>, which is the page's banner landmark when it isn't inside an <article>,
<aside>, <main>, <nav> or <section>. Give it render={<div />} when it heads a panel
that isn't the page's own.
StickyHeaderTitle echoes the page's own heading, given by watch. It rises into the header
once that heading has gone under it, and screen readers skip it, since they already reach the
heading itself.
The header sets the container's scroll-padding-top to its own height, so a link to an anchor,
or a field that takes focus, lands below it rather than under it. Pass scrollPadding={false} to
leave the container alone.
Composition
Props
The tables leave out className, style and render. Parts built on Base UI take them as its styling and composition guides describe.
StickyHeader
StickyHeaderTitle
useScrolledPast
The title tells when the page's heading has gone under the header with the use-scrolled-past
hook, which comes with them. It returns true once the element given has
scrolled up past the top of its container, or past a line offset pixels below it, using an
IntersectionObserver rather than listening to every scroll.
It takes the scroll container as root when it isn't the nearest one, and stops watching while
enabled is false.