CSS Scroll Snap gives browsers native control over scroll positions, creating gallery carousels, full-screen section layouts, and step-by-step onboarding flows without a single line of JavaScript. Applying scroll-snap-type: x mandatory to a horizontal container and scroll-snap-align: start to each child snaps each card precisely into view as the user swipes or scrolls. The mandatory value forces the viewport to always rest on a snap point, while proximity only snaps when the scroll position is close to one — choosing correctly prevents the jarring behaviour users report in content-heavy sliders. Smooth scroll throughout the page is a single property: scroll-behavior: smooth on the html element, which WordPress themes can add via a small wp_add_inline_style() call instead of a JavaScript plugin. The scroll-margin-top property compensates for sticky headers — when an anchor link scrolls to a heading, the heading stops that many pixels below the viewport top, preventing it from hiding under the fixed navigation bar. scroll-padding-top on the scroll container achieves the same result for contained scroll areas and tab panels. Combined with CSS custom properties from theme.json, scroll snap values can be token-driven and consistent across an entire block theme. Prefixing the scroll snap container with overscroll-behavior: contain prevents the parent page from scrolling when the slider reaches its end — a common complaint on sites that embed carousels in a scrollable page. Browser support for Scroll Snap is at 97 percent global coverage as of 2022, making it safe to ship without a JavaScript fallback for general audiences. The CSS grid post pairs well here — grid defines the multi-column layout while scroll snap controls the interactive slider behaviour within the same structure. The PurgeCSS guide explains how to ensure only the scroll snap rules needed for each page are shipped in the CSS. Testing scroll snap on iOS Safari is essential because its implementation historically differed from Chrome — especially for vertical full-screen snapping on long-form pages.
Problem: WordPress themes use jQuery carousel plugins to implement horizontal sliders and scroll-snapping layouts, adding JavaScript overhead for behaviour that CSS now handles natively.
Solution: Replace slider JavaScript with scroll-snap-type on the container and scroll-snap-align on each item, and add scroll-margin-top to all headings to fix anchor-link offsets caused by sticky headers.
/* Horizontal card slider — no JavaScript required */
.card-slider {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior-x: contain;
gap: 1.5rem;
padding: 1rem;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.card-slider::-webkit-scrollbar { display: none; }
.card-slider > .card {
flex: 0 0 clamp(260px, 80vw, 340px);
scroll-snap-align: start;
}
/* Smooth scroll for the entire page */
html {
scroll-behavior: smooth;
}
/* Fix anchor links under a sticky header (adjust to header height) */
h2, h3, h4 {
scroll-margin-top: 80px;
}
/* Vertical full-screen sections */
.sections-wrap {
height: 100vh;
overflow-y: scroll;
scroll-snap-type: y mandatory;
}
.section {
height: 100vh;
scroll-snap-align: start;
display: flex;
align-items: center;
justify-content: center;
}
NOTE: Add scroll-padding-top: 80px to the html element as an alternative to per-heading scroll-margin-top — the padding approach applies globally and is easier to maintain when the header height is stored as a CSS custom property.