- From: Botond Ballo via GitHub <noreply@w3.org>
- Date: Mon, 06 Apr 2026 21:26:58 +0000
- To: public-css-archive@w3.org
theres-waldo has just created a new issue for https://github.com/w3c/csswg-drafts:
== [cssom-view] Clarify number and order of `scroll` and `scrollend` events when a `scroll` event listener performs another scroll ==
When opening the following testcase:
```html
<style>
html {
height: 300vh;
}
</style>
<body onload="test()">
<script>
function test() {
window.addEventListener("scroll", _ => {
console.log("scroll");
});
window.addEventListener("scrollend", _ => {
console.log("scrollend");
});
window.addEventListener("scroll", _ => {
document.scrollingElement.scrollTop = 200;
}, { once: true });
document.scrollingElement.scrollTop = 100;
}
</script>
</body>
```
Safari prints `scroll`, `scroll`, `scrollend`
Chrome prints `scroll`, `scrollend`, `scroll`, `scrollend`
Firefox prints `scroll`, `scrollend`, `scroll`
Firefox's behaviour is clearly undesirable (the last event fired should be `scrollend`), but there is also behaviour divergence between Chrome and Safari.
I'm trying to understand what the spec says should happen in this scenario, but my naive reading of it suggests that even the number of `scroll` events fired should be just one (which is a behaviour no browser has)!
Here's my interpretation of the current spec, based on https://drafts.csswg.org/cssom-view/#scrolling-events:
* When the first scroll `scrollTop = 100` happens, `(doc, "scroll")` is added to the document's pending scroll events list.
* When the event loop gets to "run the scroll steps", the list of pending scroll events is iterated over. At this point it only contains the `(doc, "scroll")` entry mentioned above, so it's processed.
* At the time of processing, the entry is not yet removed from the list. (The step "empty _doc_'s pending scroll events" only happens at the end of the loop.)
* Processing the entry involves firing a `scroll` event at the document, which will run the event listener which performs `scrollTop = 200`.
* When running the event listener and performing the scroll, the following clause is reached: "If (_doc_, "scroll") is already in doc’s [pending scroll events](https://drafts.csswg.org/cssom-view/#document-pending-scroll-events), abort these steps.". Since the first entry has not yet been removed from the list, a second entry is never added, and so no `scroll` event is fired.
If my interpretation is incorrect, please let me know where I went wrong; otherwise, I think we need to make some clarifications/edits here.
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/13772 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 6 April 2026 21:26:59 UTC