JavaScript Document scrollsnapchange Event

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Document event
Limited availability
Experimental

What You’ll Learn

The Document scrollsnapchange event fires when a new scroll snap target is selected at the end of a scrolling operation on the document. Learn CSS setup on html, SnapEvent.snapTargetBlock, and five try-it labs.

01

Kind

Document event

02

Type

SnapEvent

03

Means

New snap target

04

Needs

scroll-snap-type on html

05

Key prop

snapTargetBlock

06

Status

Experimental

Introduction

CSS scroll snap can make sections “lock” into place as the user scrolls—like full-page slides. When the document itself is the snap container and a new target is chosen after scrolling ends, the browser fires scrollsnapchange on the Document.

Unlike plain scroll or scrollend, this event tells you which element became the selected snap target via a SnapEvent.

💡
Beginner tip

For Document scrollsnapchange, set scroll-snap-type on html (MDN). If snap lives on a scrolling <div>, use Element scrollsnapchange instead.

Understanding Document scrollsnapchange

A Document event that answers: “Did scrolling end with a newly selected snap target on the document container?”

  • Fires on the document scroll container when a new snap target is selected at the end of scrolling (MDN).
  • Requires the HTML document as snap container (scroll-snap-type on html).
  • Event typeSnapEvent (inherits from Event).
  • Useful propertiesevent.snapTargetBlock (and snapTargetInline when relevant).
  • Handlerdocument.onscrollsnapchange or addEventListener("scrollsnapchange", ...).
  • Status — Experimental and Limited availability on MDN (not Baseline).

📝 Syntax

Use the event name with addEventListener, or set the handler property:

JavaScript
addEventListener("scrollsnapchange", (event) => { });

onscrollsnapchange = (event) => { };

Event type

A SnapEvent, which inherits from the generic Event type.

MDN-style handler

JavaScript
document.addEventListener("scrollsnapchange", (event) => {
  event.snapTargetBlock.classList.add("selected");
});

Minimal CSS setup (Document as snap container)

JavaScript
html {
  scroll-snap-type: block mandatory;
}

section {
  scroll-snap-align: start;
  min-height: 100vh;
}

🔍 What Is a SnapEvent?

SnapEvent extends Event with snap-target references so you can style or announce the newly selected section.

PropertyBeginner meaning
snapTargetBlockElement selected as snap target on the block axis (often vertical)
snapTargetInlineElement selected on the inline axis (often horizontal), when applicable

⚡ Quick Reference

GoalCode / note
Listendocument.addEventListener("scrollsnapchange", fn)
Handler propertydocument.onscrollsnapchange = fn
Selected sectionevent.snapTargetBlock
Enable document snaphtml { scroll-snap-type: block mandatory; }
Sibling settled eventscrollend
MDN statusExperimental & Limited availability

🔍 At a Glance

Four facts to remember about Document scrollsnapchange.

Event type
SnapEvent

Has snap targets

Means
New snap

Target selected

CSS
on html

scroll-snap-type

Status
Experimental

Not Baseline

Examples Gallery

Examples follow MDN Document: scrollsnapchange event. Labs use document-level CSS snap. Support is limited—feature-detect and scroll to snap.

📚 Getting Started

MDN SnapEvent handler and the property form.

Example 1 — Add selected Class (MDN)

When a new block snap target is chosen, mark it with a CSS class.

JavaScript
document.addEventListener("scrollsnapchange", (event) => {
  document.querySelectorAll(".selected").forEach((el) => {
    el.classList.remove("selected");
  });
  if (event.snapTargetBlock) {
    event.snapTargetBlock.classList.add("selected");
  }
});
Try It Yourself

How It Works

MDN’s sample adds selected to snapTargetBlock. Clearing older selections first keeps only one highlighted section.

Example 2 — document.onscrollsnapchange

Use the handler property and log the target’s id.

JavaScript
const out = document.getElementById("out");

document.onscrollsnapchange = (event) => {
  const t = event.snapTargetBlock;
  out.textContent = t
    ? "Snapped to #" + (t.id || t.tagName)
    : "scrollsnapchange (no snapTargetBlock)";
};
Try It Yourself

How It Works

Prefer addEventListener for multiple listeners. The property form is fine for demos and matches MDN’s syntax listing.

📈 Detect, Label & Pair Events

Feature detection and combining with scrollend.

Example 3 — Feature Detect

Check for onscrollsnapchange before relying on the event.

JavaScript
const out = document.getElementById("out");
const supported = "onscrollsnapchange" in document;

out.textContent = supported
  ? "scrollsnapchange supported — scroll to snap"
  : "scrollsnapchange missing — CSS snap may still work";

if (supported) {
  document.addEventListener("scrollsnapchange", (event) => {
    out.textContent = "New snap: " + (event.snapTargetBlock && event.snapTargetBlock.id);
  });
}
Try It Yourself

How It Works

CSS snap can work without this JS event. Treat the listener as enhancement for highlighting or analytics.

Example 4 — Sticky Label for Current Slide

Update a sticky caption from snapTargetBlock text or data attributes.

JavaScript
const label = document.getElementById("label");

document.addEventListener("scrollsnapchange", (event) => {
  const t = event.snapTargetBlock;
  if (!t) return;
  label.textContent =
    t.dataset.title || t.getAttribute("aria-label") || t.id || "Section";
});
Try It Yourself

How It Works

Great for slideshow-style pages: the caption always reflects the snapped section without polling scrollY.

Example 5 — Pair with scrollend

Log both settled scroll and snap selection when available.

JavaScript
const out = document.getElementById("out");

document.addEventListener("scrollend", () => {
  out.textContent = "scrollend @ Y=" + Math.round(window.scrollY);
});

if ("onscrollsnapchange" in document) {
  document.addEventListener("scrollsnapchange", (event) => {
    const id = event.snapTargetBlock && event.snapTargetBlock.id;
    out.textContent =
      "scrollsnapchange → #" + id + " (Y=" + Math.round(window.scrollY) + ")";
  });
}
Try It Yourself

How It Works

scrollend confirms motion settled; scrollsnapchange names the chosen snap child. Together they describe “finished” and “which slide.”

🚀 Common Use Cases

  • Highlighting the active full-page section after snap.
  • Updating a sticky caption / progress dots for slideshow layouts.
  • Analytics for which snap slide users land on.
  • Triggering section animations only when a snap target is selected.
  • Teaching CSS scroll snap + progressive JS enhancement.

🔧 How It Works

1

CSS makes html a snap container

scroll-snap-type on html; children use scroll-snap-align.

CSS
2

User scrolls

The browser snaps toward a valid target section.

Scroll
3

New snap target selected

At the end of the scrolling operation, a child becomes the selected target.

Select
4

scrollsnapchange fires

Read event.snapTargetBlock and update UI.

📝 Notes

  • MDN: Experimental and Limited availability—Experimental banner shown above.
  • Not Deprecated or Non-standard.
  • Document event needs snap on html; Element overflow snap uses Element events.
  • CSS snap can work without JS—use the event for enhancement only.
  • Related learning: scrollsnapchanging, scrollend, scroll, JavaScript hub.

Browser Support

Document scrollsnapchange is marked Experimental and Limited availability on MDN (not Baseline). Logos use the shared browser-image-sprite.png sprite from this project. Feature-detect and keep CSS snap usable without the event.

Experimental · Limited availability

Document scrollsnapchange

Fires when a new scroll snap target is selected on the document snap container.

Limited Check compat
Google Chrome Check BCD / Chromium scroll snap events
Partial
Mozilla Firefox Limited / check BCD
Limited
Apple Safari Limited / check BCD
Limited
Microsoft Edge Follow Chromium (check BCD)
Partial
Opera Follow Chromium behavior
Partial
Internet Explorer No scrollsnapchange
Not supported
scrollsnapchange Limited availability

Bottom line: Set scroll-snap-type on html, listen for scrollsnapchange, read SnapEvent.snapTargetBlock, and feature-detect before production.

Conclusion

Document scrollsnapchange connects CSS scroll snap to JavaScript: when a new document snap target is selected, you get a SnapEvent with snapTargetBlock. Keep CSS snap as the core UX and use the event as progressive enhancement.

Continue with scrollsnapchanging, scrollend, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Put scroll-snap-type on html for Document events
  • Read event.snapTargetBlock for the selected section
  • Feature-detect "onscrollsnapchange" in document
  • Keep CSS snap usable without JS
  • Pair with scrollend when you also need settled position

❌ Don’t

  • Expect Baseline Widely available support today
  • Listen on Document for a nested overflow snap box
  • Assume every browser exposes SnapEvent
  • Rely on the event for core navigation (CSS first)
  • Ignore MDN Experimental / Limited availability warnings

Key Takeaways

Knowledge Unlocked

Five things to remember about Document scrollsnapchange

New snap target selected — SnapEvent points to the section.

5
Core concepts
🎨 02

SnapEvent

snapTargetBlock

API
💻 03

CSS on html

scroll-snap-type

Setup
🔍 04

Detect

before relying

Compat
⚠️ 05

Experimental

not Baseline

MDN

❓ Frequently Asked Questions

It fires on the document scroll container at the end of a scrolling operation when a new scroll snap target is selected. The Document must be the scroll snap container (scroll-snap-type set on html).
MDN marks Document scrollsnapchange as Experimental and Limited availability (not Baseline). It is not Deprecated or Non-standard. Feature-detect before production use.
A SnapEvent, which inherits from Event. Use event.snapTargetBlock (and snapTargetInline when relevant) to get the newly selected snap target element.
Set scroll-snap-type on the html element (for example scroll-snap-type: block mandatory) and scroll-snap-align on the snap children. MDN’s Document example uses that pattern.
scrollend means scrolling finished. scrollsnapchange means a new snap target was selected at the end of a scrolling operation. You often use both together.
Same idea for an Element that is the scroll snap container (overflow + scroll-snap-type on that element). Document scrollsnapchange is for when the overall document (html) is the snap container.
Did you know?

Scroll snap itself is mostly CSS. Events like scrollsnapchange exist so scripts can react when the browser has already chosen a target—without guessing from raw scrollY math.

Next: Document scrollsnapchanging

Learn when a snap target is pending before the final selection.

scrollsnapchanging →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful