Scroll reset
Three scroll properties worth setting globally: smooth anchoring, a scroll-margin-top offset for fixed headers, and overscroll-behavior: none to prevent the browser bounce on locked UI.
scroll-behavior: smoothanimated jump-to-anchor navigationscroll-margin-top: 5remoffset anchors below fixed header heightoverscroll-behavior: noneno bounce / pull-to-refresh on scroll lockQuick implementation
/* Smooth scrolling — respects prefers-reduced-motion */
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
/* Offset anchor scroll destination below a fixed header */
:target {
scroll-margin-top: 5rem; /* match your header height */
}
/* Apply to all heading anchors on docs/blog sites */
[id] {
scroll-margin-top: 5rem;
}
/* Prevent pull-to-refresh and overscroll bounce on modal/drawer */
.modal,
.drawer,
[data-scroll-lock] {
overscroll-behavior: contain;
}
/* Full app shell — no browser bounce at all */
body {
overscroll-behavior: none;
}
Prompt this to your LLM
Includes role, constraints, framework variants, and edge cases.
You are a senior frontend engineer writing a CSS scroll reset
for a content site with a fixed 64px navbar.
Goal: Set sensible global scroll defaults using only CSS.
Include:
- smooth scroll-behavior wrapped in prefers-reduced-motion
(never apply smooth scroll unconditionally — it can cause motion
sickness for users with vestibular disorders)
- scroll-margin-top: 5rem on [id] and :target to offset anchors
below the fixed header — without this, heading links are hidden
behind the navbar
- overscroll-behavior: contain on modals/drawers to prevent
background scroll chain
- overscroll-behavior: none on body only for app shells (not content
sites — it breaks browser swipe-back gesture on mobile)
Explain the difference between overscroll-behavior: none vs contain.
Framework variant: Show how to implement this in a Next.js app where
the fixed header height is controlled by a CSS custom property
--header-h: 4rem, and how to update that property on resize with
a ResizeObserver.
Return only the CSS with inline comments.
scroll-margin-top and fixed headers
When a page has a fixed header and a user clicks an in-page anchor link (<a href="#section">), the browser scrolls the target element to the top of the viewport — directly under the fixed header. The content is technically at the right position in the DOM, but visually it's hidden. scroll-margin-top: 5rem adds a gap above the element when it's scrolled into view, pushing it below the header. The value should match your header's height. Setting it on [id] covers every heading with an anchor, including those generated by markdown processors like remark.
overscroll-behavior: contain vs none
overscroll-behavior: contain prevents the scroll event from propagating to the parent when the child scrollable area hits its boundary — useful for modals and drawers where you don't want background page scrolling. overscroll-behavior: none also prevents the pull-to-refresh gesture and browser navigation swipes. Use none sparingly — removing swipe-back navigation is a significant UX degradation on mobile. Reserve it for full-screen app shells where those gestures don't make sense.