Skip to content
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

[scroll-animations-1] blocking effects of timeline-scope #8915

Open
fantasai opened this issue Jun 5, 2023 · 19 comments
Open

[scroll-animations-1] blocking effects of timeline-scope #8915

fantasai opened this issue Jun 5, 2023 · 19 comments

Comments

@fantasai
Copy link
Collaborator

fantasai commented Jun 5, 2023

We added timeline-scope in #7759:

timeline-scope: none | <custom-ident>

Based on some clarifications from @flackr it seems the intention is not only to pull up the scope of a named descendant timeline, but also to block it from being further pulled up by a higher ancestor. (Also, due to error-handling, names declared that have zero or multiple possible descendant timeline bindings are treated as declaring an inactive timeline.) Put together, that gives a definition that looks like:

This property declares the scope of the specified timeline names to extend across this element’s subtree.
This allows a named timeline (such as a named scroll progress timeline or named view progress timeline) to be referenced by elements outside the timeline-defining element’s subtree—for example, by siblings, cousins, or ancestors.
It also blocks descendant timelines with the specified names from being referenced from outside this subtree, and ancestor timelines with the specified names from being referenced within this subtree.

I'm opening this issue:

  1. to confirm that we want to have this blocking behavior.
  2. to ask if we want to add
    • a keyword to perform this blocking function on all possible timeline names (contain?)
    • a keyword to perform this blocking function all timeline names declared by this element (local?)
@flackr
Copy link
Contributor

flackr commented Jun 8, 2023

Making timeline-scope block propagation of a named timeline allows subtrees to use named timelines without worrying about conflicts with ancestors using the same names. e.g.

<div style="timeline-scope: --timeline">
  ....
  <div id="subtree" style="timeline-scope: --timeline">
    ...
    <!-- This is the --timeline used by anything inside of #subtree -->
    <div id="inner-timeline" style="view-timeline: --timeline;"></div>
  </div>
  ...
  <!-- This is the --timeline used by anything outside of #subtree -->
  <div id="outer-timeline" style="view-timeline: --timeline;"></div>
</div>

The downside is if you actually wanted to use the #inner-timeline named timeline you wouldn't have access to it without removing the intermediate timeline-scope declaration. Removing this would not break things in pages which did not separately define a timeline in the outer scope so as long as a developer controls the subtree it seems flexible.

IMO this allows for similar setups to custom variables where the #subtree can redefine a timeline such that it has a different timeline for that subtree.

If we don't block the propagation, the --timeline in the outer tree becomes invalid due to multiple timelines attaching to that name and so developers have to be careful to not use names that could conflict with an ancestor named timeline.

@bramus
Copy link
Contributor

bramus commented Jun 20, 2023

Hadn’t considered this before, but must say I am OK with the current behavior. It would allow re-use of the CSS – e.g. a utility-class – when nesting elements with timelines and – as flackr@ mentioned – wouldn’t break things because no two timelines want to attach to the same scope.

Should a more broader scope be needed, an author can always move up the timeline-scope declaration. I think this is something they’d want to be very explicit about, without external factors _(read: outer components) suddenly doing so while breaking things along the way.

@fantasai
Copy link
Collaborator Author

Thinking about it more, keywords here probably should be contain-all and contain-self if we go down the adding-keywords route.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [scroll-animations-1] blocking effects of timeline-scope, and agreed to the following:

  • RESOLVED: A timeline-scope also prevents the timeline from being scoped even higher.
  • RESOLVED: contain:style prevents timeline names from leaking out past it
  • RESOLVED: Don't add any additional keywords to timeline-scope for this use-case (for now)
The full IRC log of that discussion <TabAtkins> fantasai: I just wanted to confirm with the WG the behavior
<TabAtkins> fantasai: The timelie-scope property is defined to pull the scope of a timeline name up to an ancestor, which makes it available to a larger subtree
<TabAtkins> fantasai: as we were drafting, robert clarified that it also blocks the timeline from being pulled further up into a higher ancestor
<TabAtkins> fantasai: so i'm just confirming that it desired behavior
<TabAtkins> fantasai: and second to ask if we want to add keywords to make this blockign behavior work for all timeline names on an element
<TabAtkins> flackr: the motivation is that if you define a timeline scope for an element, you're isolating the effects of the timeline named there from affecting anything outside that element
<TabAtkins> flackr: so it's similar to containment in a way
<TabAtkins> fantasai: so any thoughts or comments about this blockign behavior?
<TabAtkins> fantasai: if it seems good we can resolve on that
<TabAtkins> (don't really have an opinion, seems fine)
<TabAtkins> astearns: objections?
<TabAtkins> RESOLVED: A timeline-scope also prevents the timeline from being scoped even higher.
<TabAtkins> fantasai: do we want to add keywords that add this scope-blocking on all possible names in a subtree, or all names declared by the element with timeline-scope?
<TabAtkins> fantasai: So if you're doing a bunch on a subtree, you want none of the timleine names to escape the subtree, you don't want to list them all out
<TabAtkins> fantasai: or if you're declaring several that you want to be scoped but you don't wnat to block your children from lifting their scopes, maybe a local thing
<TabAtkins> astearns: apologies, not actually clear what this would do, i assume rob and others have an opinion?
<TabAtkins> fantasai: will explain again. if you declare scroll-timeline on a scroller it's available to its descendants only
<TabAtkins> fantasai: If you want that timeline avaialble higher, you ahve to use timeline-scope on an ancestor referring to it, then it's visible to the scoping element's descendants.
<TabAtkins> fantasai: The blocking effect we jsut talked about means it can't go even higher
<TabAtkins> fantasai: [explains in more detail]
<TabAtkins> fantasai: if you want to encapsulate all the possible scrollers inside you, you might not know all the names on your contents
<flackr> q+
<TabAtkins> fantasai: if you're in a component or whatever
<astearns> ack fremy
<TabAtkins> fantasai: some higher element in your chain might say "timeline-scope: foo" and not be looking for your "foo" timeline, but another one it knows about. but it finds yours instead.
<TabAtkins> fantasai: To prevent this you ahve to preemptively timeline-scope all of your names.
<astearns> ack flackr
<TabAtkins> fantasai: so do we want to make this easier
<TabAtkins> flackr: it feels a bit odd to re-use timeline-scope for this since you're not raising the scope
<TabAtkins> flackr: coudl we say contain:style prevents the leakage or would that be too restrictive?
<TabAtkins> fantasai: think that's a good idea anyway
<TabAtkins> flackr: if we need that, do we need a timeline-scope:all?
<TabAtkins> fantasai: we might bea ble to get away without it, yeah
<TabAtkins> I agree that contain:style should prevent names leaking out
<TabAtkins> that's the point
<TabAtkins> flackr: so that's my proposal, use contain:style
<TabAtkins> fantasai: sounds good
<TabAtkins> astearns: yeah makes sense
<ydaniv> +1
<TabAtkins> astearns: any other opinions?
<TabAtkins> astearns: objections?
<emilio> q+
<TabAtkins> emilio: are there use-cases for scoping timeline names but not counters?
<TabAtkins> astearns: whether or not there is, shoudl contain:style scope both anyway?
<TabAtkins> emilio: it should yeah
<TabAtkins> astearns: so i think we can resolve on contain:style and then your question is about maybe still adding a separate control
<emilio> ack emilio
<TabAtkins> astearns: so any objections to contain:style?
<TabAtkins> RESOLVED: contain:style prevents timeline names from leaking out past it
<TabAtkins> astearns: so emilio's question is an argument for adding a keyword to do just the one thing
<TabAtkins> astearns: i can't immediatly think of a case where you'd want to do them separately
<TabAtkins> fantasai: If we did add the keywords, i just thought of 'contain-all' and 'contain-self'
<flackr> q+
<TabAtkins> astearns: i suggest we leave the keywords out until we have evidence that just using contain:style is insufficient
<astearns> ack flackr
<TabAtkins> flackr: if we did have an "all" on timeline scope, I'd also expect them to raise the scopes they captured
<TabAtkins> fantasai: yeah that's why i thought of the "contain-*" names to separate them a little more from that concept
<TabAtkins> flackr: ah right. but for now I think we're comfortable with not doing this
<TabAtkins> fantasai: so proposed resolution is to not add keywords for ow
<TabAtkins> astearns: objections?
<TabAtkins> RESOLVED: Don't add any additional keywords to timeline-scope for this use-case (for now)
<fantasai> Side comment: 'contain: style' should probably also affect anchor-name

@andruud
Copy link
Member

andruud commented Aug 21, 2023

RESOLVED: contain:style prevents timeline names from leaking out past it

This means you can't lift names across CQ-containers, is that what we want?

@ydaniv
Copy link
Contributor

ydaniv commented Aug 21, 2023

This means you can't lift names across CQ-containers, is that what we want?

Would it make sense to add contain: timelines?

@flackr
Copy link
Contributor

flackr commented Aug 21, 2023

This means you can't lift names across CQ-containers, is that what we want?

That's a good question. It does feel like an odd restriction that could surprise / prevent some developers from doing what they want.

Would it make sense to add contain: timelines?

We could always add a contain: timelines at any point, no need to rush to do it now in case there are other things in the same vein as timeline names we would also want to contain.

@andruud
Copy link
Member

andruud commented Sep 18, 2023

Agenda+ to confirm that we indeed want CQ-containers to block timeline names from escaping.

@ydaniv
Copy link
Contributor

ydaniv commented Sep 28, 2023

Thinking again on what @frivoal said last meeting regarding containment, it's main purpose is to provide a performance optimization.
@andruud, is there any benefit from containment of timeline names?
If not, I suppose it could be handy to contain names so they don't interfere with higher scope, but as an intentional opt-in, and not otherwise.

@andruud
Copy link
Member

andruud commented Oct 3, 2023

@ydaniv I suppose there would be a minor benefit. When trying to connect scroll/view timelines with deferred timelines (produced by timeline-scope), we could early-out at the contained element. But it's very minor, and there are probably other ways to optimize this even without containment.

@ydaniv
Copy link
Contributor

ydaniv commented Oct 3, 2023

We already have timeline-scope for scoping, I propose we reverse the decision on scoping with contain: style

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [scroll-animations-1] blocking effects of timeline-scope.

The full IRC log of that discussion <dael> astearns: On the agenda to confirm we do want style containers to block timeline names from escaping. Is it continer queries or style queries?
<dael> florian: Continer query on which style is based?
<dael> astearns: Anyone have a better handle on this?
<dael> florian: Superficially this seems fine to me
<dael> astearns: We had already resolved we'd not allow timelines to escape a conteiner of some kind
<dael> miriam: Contianment for container queries includes style. If you set up an inline size container you are implicitly adding style containment. That's scope the timeline name
<dael> flackr: And that seemed unnecessary restriction and might want to scope the layout that has containment
<dael> astearns: From my recollection we have other names that don't leak. I think just doing this to be consistent?
<dael> florian: I think...I think it would be appropriate to spend more time on this. Containment is not just useful behavior, but guar. that certain constraints are matched. Just because we can't immediately find a case where there's a problem doesn't mean there isn't one.
<flackr> qq+
<dael> florian: If we build this and the web depends on it but it doesn't work that breaks container queries. We don't want to defeat containment by doing this.
<dael> vlad: I think this is an observation that lets us skip work in subtree. If these names escape the work becomes necessary
<dael> flackr: Agree. If we want to leak butter to say size containment doesn't require strict style containment
<dael> flackr: Issue came about b/c using a container query
<dael> florian: Types of containment don't have dependency, but continer queries use both
<dael> flackr: I think that's what we're getting at, the core. You shoudl be able to leak names even if have container
<dael> florian: So style is strict but not invoked
<dael> miriam: Have to do part b/c counters escaping
<dael> flackr: Need to think through
<dael> florian: That means breaking style containment into two things. One is involked by container and the other is not but is by content visbility.
<dael> florian: I suspect explicit values are better if we go there
<dael> astearns: We're not going to get to a resolution today. Let's take it back to the issue and try and work this through

@astearns astearns removed the Agenda+ label Dec 7, 2023
@flackr
Copy link
Contributor

flackr commented Jan 9, 2024

For a strawman proposal, I suggest we break style containment into two parts:

  1. Contain named items (e.g. scroll-timeline-name, view-timeline-name, anything else, maybe counters?)
  2. Everything else? Maybe someone who's more knowledgeable about what restrictions container queries need could comment which parts of style containment are needed here. Maybe those not needed could be grouped into bucket 1.

Assuming this split, container-type would only apply the second part, allowing named items to leak out, while content-visibility skipping contents would apply both since we avoid needing to compute style for any of the descendents.

Then, we have to decide on the behavior of the contain property:

  1. Does contain: style means both parts? I'd lead towards yes, but could see going both ways.
  2. Do we expose keywords for the finer grained parts? If so, which ones?

@vmpstr
Copy link
Member

vmpstr commented Feb 8, 2024

We ran into a similar issue in a context of #9890 where we'd like to have a property that limits how far up the tree view-transition-name is exposed. The initial thinking was something along the lines of a view-transition-scope that establishes a view transition scope and no name can escape it. @bramus pointed out that this is better suited for things like a new container-type.

We further discussed this and are now thinking that perhaps we need a containment value that does this name limiting. This goes in line with the proposal here: break contain: style into more categories with future proofing to allows us to extend this in the future if needed.

@khushalsagar
Copy link
Member

Do we expose keywords for the finer grained parts? If so, which ones?

I'd say yes. We could have keywords per feature, like scroll-timeline, view-timeline, view-transition for names associated with the particular feature and a shorthand all for convenience.

@ydaniv
Copy link
Contributor

ydaniv commented Mar 9, 2024

If style currently only includes counters and quotes, how about adding a new value for that, like text-formatting, and then we can keep style as "includes all" while allowing other values to escape that containment?

@bramus
Copy link
Contributor

bramus commented Jun 17, 2024

Cross-referencing #10145 after the naming discussion and the names escaping the Shadow DOM sparked again there.

Building onto Flackr’s proposal: what if we had a separate keyword to contain the names? And what if it was a function?

Something like:

  • contain: names(all)
  • contain: names(none)
  • contain: names(view-transition scroll-timeline)

(Could also be a property contain-names with view-transition as value … but you get the idea)

The UA stylesheet could sport something like :host { contain: names(all); }. Names that are not contained would “bubble up”, limited to names defined in custom elements that have an open shadow root (closed shadow roots would be excluded).

@khushalsagar
Copy link
Member

^ this proposal means you have an all or nothing bubbling up of names and I'm not sure if that's enough encapsulation. Especially with scoped transitions where a component could drive transitions completely internally and wouldn't want all those names to bubble up. Maybe a keyword for all the naming CSS properties to indicate if this should cross tree scope..?

Also, how do we feel about the other way around. Should named declared on nodes in the outer tree scope be visible inside? Maybe an element in the shadow DOM needs to anchor to some content in the outer DOM.

@bramus
Copy link
Contributor

bramus commented Jun 28, 2024

^ this proposal means you have an all or nothing bubbling up of names and I'm not sure if that's enough encapsulation.

It would be selective, e.g. contain: names(view-transition scroll-timeline) would only contain the names defined by those properties. Other names – in this example keyframes and anchor-name – can bubble up.

(Admittedly this quite quickly taps into Additive CSS, where an author would like to extend that list with an extra value)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants