Scrolling

CSS controls how scrolling feels: smooth jumps to anchors, carousels that snap into place, headers that don't cover jump targets, styled scrollbars, and scroll containers that don't drag the whole page along. This lesson covers the scrolling toolkit.

Smooth scrolling

Try it yourself
Result

scroll-behavior: smooth (usually on html) animates jumps to anchor links. Disable it for users who prefer reduced motion.

scroll-margin: offset for sticky headers

Try it yourself
Result

When a page has a sticky header, anchor jumps land underneath it. scroll-margin-top on the targets leaves room. (scroll-padding-top on the scroll container does the same for all targets at once.)

Scroll snap

Try it yourself
Result
  • scroll-snap-type on the container: the axis (x, y, both) and strictness (mandatory always snaps; proximity snaps only when close).
  • scroll-snap-align on the children: start, center or end.
  • scroll-snap-stop: always prevents fast swipes from skipping items.

A CSS-only carousel like this works with touch, trackpads, mouse wheels and keyboard arrows (once focused).

overscroll-behavior

Try it yourself
Result

By default, reaching the end of a scrollable area hands the scroll to the page ("scroll chaining"). overscroll-behavior: contain stops that — essential for modals, side drawers and chat panels. It also disables pull-to-refresh when applied to the page.

Scrollbar styling

Try it yourself
Result

The standard properties scrollbar-width (auto, thin, none) and scrollbar-color (thumb then track) work in all current browsers. Don't hide scrollbars on content people need to scroll — it hides the fact that there's more.

Sticky elements

position: sticky (lesson 24) keeps headers, table headings and sidebars visible while their container scrolls. Remember it only works inside the nearest scrolling ancestor and needs a top (or other) offset.

Scroll-linked effects

Scroll-driven animations (lesson 38) tie animation progress to scroll position — progress bars, parallax and reveal-on-scroll effects with no JavaScript. Combine them with prefers-reduced-motion checks.

Try it yourself

Try it yourself
Result