#306: CSS content-visibility property

Visit on Github.

Opened Sep 10, 2018

Bonjour TAG,

I'm requesting a TAG review of:

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify [github usernames]

Discussions

Comment by @kenchris Oct 31, 2018 (See Github)

At TPAC, it sounded as there is some overlap between this and the Invisible Searchable DOM proposals and that you needed to work out what solution to promote or whether you could come up with a new joined proposal.

In the light of that, are you still looking for feedback on this proposal at this time?

@rakina

Comment by @kenchris May 22, 2019 (See Github)

Given the opposition from Apple and Mozilla (see https://github.com/WICG/virtual-scroller/issues/164) is this moving forward, and worth out time to review in details?

Comment by @chrishtr May 23, 2019 (See Github)

Hi,

Yes, we are still moving forward with this feature. We are working on improved explanations, use cases and demos to address the concerns raised in earlier discussions.

I agree that it's ok to hold off on reviewing for now, until we ping this issue again. Thanks!

Discussed Jun 19, 2019 (See Github)

Sangwhan: Being redesigned, waiting for editor updates.

David: Some mozilla folks wrote a position paper.

Dan: Should we set a milestone to come back and look at it again?

Sangwhan: No, let's wait till they come back to us.

Comment by @kenchris Sep 10, 2019 (See Github)

@chrishtr any update on this?

Comment by @chrishtr Sep 11, 2019 (See Github)

Hi,

Yes, there are some pretty big updates in the last few weeks!

In particular, based on feedback, we've significantly reworked the API shape. The new API takes into account the various pieces of feedback we've received from the community, some early-adopter experience, and drawbacks we discovered while implementing the previous API:

  • The API is now declarative via a new rendersubtree HTML attribute to control rendering, and a content-size CSS property to express intrinsic sizing
  • The declarative shape integrates much more easily with the way that rendering and the cascade generally work, allows adoption without any user script, and avoids significant complexity
  • It also avoids a performance cliff / design flaw in the old API, where pages could get into a state where CSS containment isolation and locking state disagreed
  • There are no "stale pixels" or "update in the background" methods in the current design iteration

I think the new API shape should admit an implementation of rendersubtree and content-size for existing browsers without a ton of effort, and already benefits use cases like (a) page loading performance, (b) infinite scrollers, and (c) makes it easier to add accessibility without sacrificing rendering speed, via the activation concept.

A "yielding" renderer, multi-threading or other advanced tech is not needed. I think this particular point addresses what may be the biggest concern raised in this issue.

A new explainer is here. Thanks for taking another look.

Comment by @torgo Sep 12, 2019 (See Github)

One minor thing worth noting: You state in the first para of the motivation section that "web developers need ways to reduce loading and rendering time of web apps that have a lot of DOM." I wish you would explicitly call out the user-facing need that leads to this. Something like: "faster rendering of pages creates an overall better user experience" just so that it's clear where the developer need springs from - and that what we are doing here is in service of the user experience.

Comment by @dbaron Sep 12, 2019 (See Github)

I'd like to look into this further, but one comment after just a few minutes is that this text:

rendersubtree, when present, forces style and layout containment, plus size containment if invisible.

This seems a little bit confusing since those containment values need to persist after rendersubtree is removed. So it seems like there needs to be some mechanism for that persistence.

Comment by @chrishtr Sep 14, 2019 (See Github)

One minor thing worth noting: You state in the first para of the motivation section that "web developers need ways to reduce loading and rendering time of web apps that have a lot of DOM." I wish you would explicitly call out the user-facing need that leads to this. Something like: "faster rendering of pages creates an overall better user experience" just so that it's clear where the developer need springs from - and that what we are doing here is in service of the user experience.

Thanks for this - I added a paragraph saying this.


I'd like to look into this further, but one comment after just a few minutes is that this text:

I appreciate you taking another look!

rendersubtree, when present, forces style and layout containment, plus size containment if invisible.

This seems a little bit confusing since those containment values need to persist after rendersubtree is removed. So it seems like there needs to be some mechanism for that persistence.

Containment doesn't need to be perisisted after rendersubtree is removed. "Removing rendersubtree" means not setting the attribute at all, which is different than setting it to the empty string. When the User Agent performs an activation of invisible DOM, it sets rendersubtree to the empty string, which still has style and layout containment.

There is also a non-normative note that explains further that it's recommended that the developer set rendersubtree to the empty string if it intends to set it to some other value in the future, for the reason of not changing style and layout containment.

If needed, I can clarify the spec text accordingly.

Comment by @kenchris Dec 4, 2019 (See Github)

The explainer uses attribute values like rendersubtree="skip-activation" but those are not in the spec PR:

image

Is the spec text behind or should the explainer be updated?

Comment by @dbaron Mar 3, 2020 (See Github)

@kenchris and I are looking at this during the Wellington face-to-face.

We filed a bunch of issues (above) on subtree visibility.

@kenchris is concerned about the name of contain-intrinsic-size being unclear, i.e., sounding more like a boolean than a property that sets an intrinsic size but only when containment is used. (I'd still like to see the more general intrinsic-size property, though I don't recall right now what the issues blocking that were.)

We didn't get to look at the beforematch event explainer as much as we should, but we should do so in the future. Though in addition to the privacy concerns mentioned in that explainer (and perhaps others) I think we should think about whether this model might interfere with the development of future user-agent features that don't exist yet (compared to the existing find-in-page feature that is handled there). Also, when starting to read that explainer I was expecting it to have a feature that allowed addition of content that had been excluded for performance reasons... whereas it actually doesn't seem to be about that sort of thing, but instead about content that the user couldn't currently scroll to, for example because it's in a collapsed section. Or am I misunderstanding?

Comment by @dbaron Mar 3, 2020 (See Github)

One other point is that one of the use cases for beforematch seems to already be satisfied by hashchange events.

Comment by @vmpstr Mar 3, 2020 (See Github)

With regards to beforematch:

  1. It does not allow searching for any content that isn't in the DOM. However, the content that is included in the DOM can be excluded from rendering by the user-agent (e.g. in a collapsed section). The beforematch can search some of these sections and send an event allowing the developer to show the content (e.g. expand the section).
  2. hashchange seems to be an event that is tied to the fragment identifier changing. I think that can replace the fragment-link navigation part (one out of three cases) with the caveat that the script would need to parse the url fragment to find out the element id. It does not address find-in-page or scroll-to-text navigation (at least, not to my knowledge).
Comment by @kenchris Mar 3, 2020 (See Github)

The URL (and hashchange) could change/fire with the find-in-page especially with the new scroll to text fragment feature https://github.com/WICG/ScrollToTextFragment/

Comment by @vmpstr Mar 3, 2020 (See Github)

Just to clarify your last point here, do you mean that it already should fire on find-in-page and scroll-to-text, or that we should update hashchange spec so that it fires on find-in-page and scroll-to-text?

When considering find-in-page specifically, which is a primary use case for us, I think it would be somewhat awkward to have hashchange fire on a find-in-page match (mostly since the hash part of the URL doesn't change). In order to satisfy our use case, it would also have to fire on the element that contains the find-in-page match text (as opposed to on the window), which adds to the awkwardness in my opinion.

I think we can safely drop fragment-link navigation (ie #id navigation) from beforematch since that can be handled by hashchange for sure. Although in my mind it still feels like it is useful to include it in beforematch.

Comment by @kenchris Mar 3, 2020 (See Github)

Yes, it would probably have to be a fragmentchange event or similar as we are changing the url fragments. I don't know if there are any plans to change the fragments when selecting a match using find-in-page but it could make sense for copying the URL instead of having to select the text and then generate a url with the right fragment

Comment by @domenic Mar 3, 2020 (See Github)

Although in my mind it still feels like it is useful to include it in beforematch.

Strong +1. It's better to leave hashchange for being dedicated to handling hash changes, and not force developers to structure their code like

document.addEventListener("beforematch", handleBeforeMatch);
document.addEventListener("hashchange", () => {
  handleHashChange();
  handleBeforeMatch();
});

Letting "beforematch" be the one-stop-shop for this sort of handling is a much more elegant and decoupled design, instead of taking a dependency on the incidental fact that we already have an event for 1 of 3 cases.

Comment by @kenchris Mar 3, 2020 (See Github)

Maybe we can find a better name than beforematch - it wasn't really clear to me when it would fire. Like if I do find-in-page for "firefox" and it finds 3 matches, will it fire for the second one just as I click on "move to next"?

It is also not clear that match relates to find-in-page etc

Comment by @vmpstr Mar 3, 2020 (See Github)

Like if I do find-in-page for "firefox" and it finds 3 matches, will it fire for the second one just as I click on "move to next"?

Yes, that's the intended behavior

Maybe we can find a better name than beforematch

That's fair, we're discussing it here: https://github.com/WICG/display-locking/issues/115

Comment by @dbaron Mar 3, 2020 (See Github)

Strong +1. It's better to leave hashchange for being dedicated to handling hash changes, and not force developers to structure their code like

Yeah, I think that's fine. But I think it's worth mentioning the existence of hashchange in the explainer where you mention that use case.

Comment by @vmpstr Mar 6, 2020 (See Github)

After further testing (with @josepharhar's help), I'm no longer sure that my position of keeping fragment navigation is correct.

Specifically, script can change the hash and expect that the scroll be changed immediately. The way we've been thinking about beforematch is that its handler can and sometimes will change something about the rendering of the page that may shift elements around. It might be desirable to delay scroll until the event handler ran, but we can't do that for fragment link navigation without breaking the web.

I've filed https://github.com/WICG/display-locking/issues/135 to discuss this further.

Comment by @vmpstr May 11, 2020 (See Github)

Hello,

We'd like to focus only on the CSS content-visibility property in this issue (contain-intrinsic-size and beforematch events should be discussed separately if needed). The current version of the spec draft can be found here: https://drafts.csswg.org/css-contain-2/#content-visibility

We would appreciate another pass at this review!

Note: If possible please file an issue in https://github.com/w3c/csswg-drafts/issues/ with your feedback

Comment by @kenchris May 28, 2020 (See Github)

@vmpstr the spec doesn't have the hidden-matchable which the explainer says will solve use-case 2. Was that dropped and should the explainer be updated?

Comment by @atanassov May 28, 2020 (See Github)

@dbaron @kenchris and myself took another look this issue, now scoped to content-visibility only. It would be good to update the explainer to match the CSS Containment module, ex. the value hidden-matchable is no longer part of the spec.

We advise you to continue working with the CSSWG in completing the rest of the spec.

Comment by @vmpstr May 28, 2020 (See Github)

The hidden-matchable value is something that we would still like to pursue in the future but it would require a separate discussion / design review, as well as require additional features like #511 to be useful.

For now, we're focussing on the values outlined in the spec draft. I will update the explainer to separate the proposed values here from the possible new values that we are thinking of proposing.

Thanks!

Comment by @vmpstr May 28, 2020 (See Github)

I've updated this in the repo, hopefully the separation of the features is more clear now. https://github.com/WICG/display-locking/