Re: [csswg-drafts] [css-contain] content-visibility: auto visibility check timing needs details (#8542)

What do you think of the following proposal for a spec edit?

Spec edits for [step 3 and 4 of the clarifications](https://drafts.csswg.org/css-contain/#cv-notes):

During step 14.1 (“recalculate styles and update layout”) of [Update the Rendering](https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering), if an element has an `auto` used value of the `content-visibility` property and is not skipped, it computes its [on-screen status](https://drafts.csswg.org/css-contain/#relevant-to-the-user) (i.e. on-screen for relevant to the user) at that time. If this has never been done for an element, it has an indeterminate on-screen status. Elements with indeterminate on-screen status are considered not on-screen for the purpose of determining whether they are relevant to the user.

Note: on-screen status belongs to an element, not a box in the render tree, and becomes determined only once in its lifetime.

If any elements with indeterminate on-screen status change their on-screen status from indeterminate to on-screen during step 14.1, then style and layout must be subsequently updated synchronously before step 14.2. User Agents may limit the number of repeated style and layout updates during this step.

Note: this may cause style and layout to update as many times as the depth of content-visibility:auto nesting in the document. (However, content-visibility:auto elements not nested within others that started offscreen do not cause a subsequent style and layout update.)
This recursion is similar to resize observer, Step 14.4.2 of Update the Rendering, which also has a way for User Agents to limit work.

Implementation notes:

In Blink, this is implemented as a [separate delivery behavior for IntersectionObserver](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/local_frame_view.cc;l=1538;drc=43e3f5c9953f5b7544af605de36d31baf42d1c34).

As an aside, IntersectionObserver in Blink is used both as an internal class and a script exposed API. Delegates registered there can specify their own delivery behavior. The intersection observer delegate that we create for content-visibility [specifies this different delivery time](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/display_lock/display_lock_document_state.cc;l=129;drc=8101d6d81854e4f437e0f03f77694a01aaa8df7a).

This delivery always happens[ during the lifecycle, before the resize observer steps](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/local_frame_view.cc;l=2470;drc=8101d6d81854e4f437e0f03f77694a01aaa8df7a).

To implement the effect behavior in [steps 3 and 4](https://drafts.csswg.org/css-contain/#cv-notes), and determine whether it’s synchronous or asynchronous, [we query the display lock context state](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/display_lock/display_lock_document_state.cc;l=146;drc=8101d6d81854e4f437e0f03f77694a01aaa8df7a) (this is an optional per-element state) and either update it or [queue an internal task to update it at the next lifecycle](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/display_lock/display_lock_document_state.cc;l=148;drc=8101d6d81854e4f437e0f03f77694a01aaa8df7a).
This is, of course, only one possible implementation. The synchronous on-screen status determination doesn’t have to use an IntersectionObserver, and can be done in other ways. We just found it convenient to do that in Blink, because IntersectionObserver has all of the relevant geometry code.

-- 
GitHub Notification of comment by vmpstr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8542#issuecomment-1485776304 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Monday, 27 March 2023 19:56:08 UTC