-
Notifications
You must be signed in to change notification settings - Fork 707
[css-view-transitions-1] User input should be ignored when rendering is suppressed. #7797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Proposed Resolution: User input is discarded for each Document with transition suppress rendering set. |
out.mp4There are three states in terms of what the user sees:
With the real DOM, input goes to the real DOM. With the pseudos, input goes to the document element. I don't think we should add a third behaviour for the paused render case. Throwing input away could cause more of a 'glitch' in the gesture example, as dropped events would mean the initial position could be out of sync with actual pointer position. Doing a hit-test on the real DOM seems risky, as elements might be in completely different places. So, I vote that we do the same as in the "transition pseudos" state, and send events to the document element. |
Input doesn't necessarily go to the document element for the transition pseudos case. Try the following example: <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.before {
background: grey;
}
.after {
background: lightblue;
}
#target {
view-transition-name: target;
contain: layout;
}
html {
view-transition-name: none;
}
html::view-transition-new(*) {
animation-duration: 5s;
}
</style>
</head>
<body>
<script>
function flip() {
direct.classList.toggle("before");
direct.classList.toggle("after");
}
function doTransition() {
document.startViewTransition(() => {
target.classList.toggle("before");
target.classList.toggle("after");
});
}
</script>
<button class="before" onclick="doTransition()" id="target">Animate</button>
<button class="before" onclick="flip()" id="direct">Flip</button>
</body>
</html> Event handlers on DOM elements not participating in the transition continue to work throughout the transition. This is handy if your transitions changes a subset of the page. The spec intent was to handle the pseudo DOM case the same as we would for hit-testing on any other pseudo-element. For example if the pointer location of the event is That said, I'm ok with dispatching events to the document element while rendering is paused instead of dropping them entirely. I was hard pressed to think of a use-case where the developer could do anything meaningful with the events. Rendering is paused so its not like visuals can be updated in response to the event. But, if the transition is being driven by a gesture then the curve of the gesture could be used to influence the animation. The developer would need all touch move events to keep track of the curve. |
A point worth clarifying here is that this is only relevant if a hit-test is needed while rendering is paused. There could be a case where the user input starts a scroll gesture, which has locked a target node, and a transition is initiated. The target node for the gesture shouldn't change for the duration of the scroll gesture. |
That's fair. I think I'm happy with either: Option 1: Delay events until rendering is unblocked, then hit-test against what's now under the pointer. I think this will be hard to spec 😄 Option 2: Target events to the document element. I know this isn't 100% like it is when the pseudos are there, as you've detailed above, but I expect cases where the underlying DOM is revealed to be rare, especially once we have scoped view transitions. |
Summary for CSSWG: During a view transition, elements involved in the transition are hidden from the real DOM. In most cases, this means every element is hidden, because every element is somehow involved. However, if you set root's Clicks during a view transition will almost always hit one of the pseudos, because But, what should we do while the What should we do with clicks during this period? Currently on the web platform, if you block the event loop, eg with a JavaScript Option 1: Queue user inputsWe prevent tasks being taken from the user input task source during this period. It isn't a full event loop block, it just queues up input-related tasks. Then, once the transition starts, the task source will be unblocked, and hit-testing will happen as normal. There's a risk of deadlock. Eg, if This option also feels incompatible with scoped transitions, a future planned feature where multiple view transitions can run concurrently if they're scoped to independent elements. Option 2: Target pointer events to the document elementThis is what will happen during the transition in most cases anyway, except in the edge case mentioned above, where the root's |
The CSS Working Group just discussed
The full IRC log of that discussion<JakeA> https://github.com//issues/7797#issuecomment-1469931231<khush> Jake's getting 'em all! :) <fantasai> s/Topic/Subtopic/ <fantasai> s/topic: break// <emeyer> JakeA: During a transition, elements involved are hidden from the DOM <Rossen_> q <emeyer> …That usually means every element is hidden, because the root element has a transition name <emeyer> …Clicks during a transition will almost always hit the pseudo and fall to the document root <emeyer> …Authors could change this by changing the root’s transition name to none <emeyer> …Question is: what do we do with clicks while promises haven’t settled and the transition is frozen? <emeyer> …Similar case: if you block the event loop using a while loop, it will block rendering <emeyer> …If a user clicks anywhere, those events are queueing up <emeyer> …Once the freeze is thawed, the events and hit tests and such are resolved then, which may resolve hits against things that moved <emeyer> …We can’t do a full event block, but we could take from tasksources and then resolve when the transition starts <emeyer> …Deadlocks are still possible in this option, which may also conflict with scoped transitions <emeyer> …We don’t want to block all input events while scoped transition is happening <emeyer> …Option 2: we apply all events to the document element <TabAtkins> q+ <emeyer> …In that case, a click may hit the document element whereas if we’d queued it, it might have hit a more specific element <flackr> q+ <khush> +1 for option 2. <emeyer> Rossen: I want to make sure we’re sticking to CSS <emeyer> TabAtkins: +1 for option 2, which seems a little safer; also I hate when things resolve against DOM I wasn’t expecting; also makes things more predictable <Rossen_> ack TabAtkins <Rossen_> ack flackr <emeyer> flackr: I think a common case is that by the time you’d dispatch the events in option 1, the elements will be where they should be <khush> q+ <emeyer> …Worried that we’re seen cases transitions to move small pieces of sub-documents <emeyer> …I strongly prefer option 1 <Rossen_> ack khush <emeyer> khush: If we decide to buffer until rendering is done, the first question is do we dispatch before or after creating the pseudo-DOM? <emeyer> …Why not just give it to the document? <emeyer> JakeA: I think flackr’s point is that if you have a pseudo-element is in a certain place, option 2 raises the chances of a thing not being where it was when the click was made <emeyer> khush: So this is for the case of rootless transitions? <emeyer> JakeA: This is all about rootless transitions <emeyer> flackr: If I start a transition on mousedown, as long as my pseudo is pointer-events: none, I can still get that click <emeyer> …I also feel like you have a halting issue regardless, since there’s no requirement a transition ever finish <chrishtr> q+ <emeyer> JakeA: Should have clarified that this deadlocks are already limited to four seconds <emeyer> flackr: So this isn’t new, it’s just we could make them more likely <emeyer> …If a developer doesn’t finish setting up for a view transition, there will be problems <emeyer> chrishtr: With option 2, if the dev starts a transition but then does nothing and we wait four seconds, if the user clicks in that 4s window, is the click lost? <emeyer> JakeA: Yeah, in option 2, the click won’t work <Rossen_> ack chrishtr <emeyer> chrishtr: So the default UA behaviors are suppressed <khush> q+ <emeyer> flackr: In option 1, we wait for the transition to fail to start, the events are processed after the transition is canceled <emeyer> chrishtr: Could we do an option 3 where user events are still processed and applied to the original target? <Rossen_> ack khush <emeyer> khush: Option 1 is very hard to reason about with scoped transitions, whichis why I’m advocating option 2 <emeyer> …The easiest thing is to dispatch an event at the root of the subtree, <vmpstr> +1 <Rossen_> ack khush <emeyer> flackr: An event targeted at the document provdes XY coords, yes? <emeyer> khush: Yes <emeyer> Rossen: We seem to be sliding to option 2; flackr, you were the main proponent of 1 <emeyer> flackr: I like that option 2 supports scoped transitions better <emeyer> …I think it’s okay <emeyer> Rossen: Any other opinions or objections to resolved on option 2? <emeyer> (silence) <JakeA> Target pointer events to the document element <JakeA> This is what will happen during the transition in most cases anyway, except in the edge case mentioned above, where the root's view-transition-name is set to none, and the clicks don't hit the pseudos. In that case, click may hit the document element, where they would hit a more specific element during the transition. <emeyer> RESOLVED: target pointer events to the document element <flackr> Or to the root of the transition for future compat with scoped transitions! |
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175}
…render-blocked, a=testonly Automatic update from web-platform-tests vt: Input targets documentElement while render-blocked This is done per the resolution in w3c/csswg-drafts#7797 (comment) This is a direct revert of commit https://crrev.com/f4b3a78fc4 which explicitly dropped input while rendering was blocked for a view transition capture. Reverting the above CL indirectly implements the desired behavior from the CSSWG resolution. The reason is that the UA stylesheet gives the ::view-transition pseudo width/height: 100% which is viewport filling. Pseudo elements already route input events to their owning DOM element, in this case the document :root. Authors cannot change this as their pseudo styles get applied only once the view transition animation starts, see [1]. [1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/view_transition/view_transition_style_tracker.cc;l=1116;drc=f599ac6c54b827d30f79a8f15bf1e2661af8925a Bug: 1424821,1368757 Change-Id: I4a0efa5180c69225cb34661c5cea3e8aba95a4d1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4362639 Reviewed-by: Ian Vollick <vollick@chromium.org> Commit-Queue: David Bokan <bokan@chromium.org> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1121175} -- wpt-commits: ffd19229368be8d06a6fd87b55018c9895d78b5f wpt-pr: 39151
#7784 details how rendering should be suppressed during a transition. We also need to ignore user input (irrespective of how rendering is suppressed) in this state. That's because the visual state of the Document displayed to the user doesn't align with the DOM state.
Note that the user agent may need to dispatch synthetic events to ensure the input stream observed by the developer makes sense. For instance, the user puts their finger down when rendering is suppressed which causes a touchstart event. If rendering is unsuppressed while the user finger is still down script would directly see a touchmove event. It makes sense to dispatch a synthetic touchstart event in this case. But this detail can be left up to the user agent.
The text was updated successfully, but these errors were encountered: