w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.38k stars 641 forks source link

[css-anchor-1] position-visibility show/hide animations #10182

Open progers opened 3 months ago

progers commented 3 months ago

Many tooltips use an animation effect. An example is the tooltips here on github: if you hover over the notification icon in the top-right, an opacity 0->1 animation is used for the tooltip. A simple proposal for anchor positioning would be:

position-visibility-show-animation: [animation-name];
position-visibility-hide-animation: [animation-name];

The current spec for position visibility (link) states that hidden anchors are strongly hidden. This would need to change so that it takes effect after the hide animation, and stop taking effect before the show-animation.

@tabatkins @una

mfreed7 commented 3 months ago

Wouldn't the new transition-behavior: allow-discrete along with this behavior allow changes in visibility triggered by position-visibility to be animated?

progers commented 3 months ago

The visibility triggered by position-visibility is internal to the engine and is not exposed to authors. https://github.com/w3c/csswg-drafts/issues/7758#issuecomment-1980302892 brought up many good points about this topic, such as tying this to the existing visibility property.

tabatkins commented 3 months ago

Yeah, I think the right approach might be:

  1. Add a new strongly-hidden value to visibility. This forces the descendants of the element to also compute to strongly-hidden, regardless of their specified value.
  2. position-visibility pivots to actually causing visibility to compute to strongly-hidden.
  3. Transitions/animations can now key off of this, using the same behavior as they currently have for hidden.
kizu commented 1 month ago

I did not see this issue when filling https://github.com/w3c/csswg-drafts/issues/10411, so I will copy its content here (and close as duplicate), as it also mentions that just having the visibility won't be enough to animate showing/hiding of something with position-visibility.


Right now, the effect of position-visibility (https://drafts.csswg.org/css-anchor-position-1/#position-visibility) is immediate, making it sometimes a bit jarring when the anchored element hides/appears.

I can see authors wanting to design this transition: through opacity, translate or any other way they want to design the regular enter/leave transition for their anchored elements.

For popovers we can design the transition via a combination of :popover-open and @starting-style (https://nerdy.dev/using-starting-style-and-transition-behavior-for-enter-and-exit-stage-effects), but for cases like with position-visibility we don't have any hooks that we currently could use for this.

I am not yet sure what the solution could be, but I am certain that we need one. Open questions:

  • Should we somehow reuse the @starting-style?
  • Will we need the @ending-style or something like that in the absence of :popover-open alternative?
  • Or could we say that when the element hides via position-visibility it uses the @starting-style if it is defined as the styles it will transition to?
  • If we'd add the above, should we have a new keyword in the transition-property to cover the visibility part of the transition itself, like position-visibility? Or we could reuse visibility there?
css-meeting-bot commented 1 month ago

The CSS Working Group just discussed [css-anchor-1] position-visibility show/hide animations, and agreed to the following:

The full IRC log of that discussion <emeyer> TabAtkins: While doing implementation work, Philip noted authors probably want to animate elements disappearing and reappearing
<emeyer> …How do we do it? Philip proposed properties for that
<emeyer> …My proposal is to have position visibility change the computed value, and key off of that to do transitions
<kizu> q+
<emeyer> …Either of these are potentially doable, but Roma has a comment just posted
<astearns> ack kizu
<emeyer> kizu: The only thing I think we don't have is an entry animation
<emeyer> …There's no way to hook on to when that fires
<emeyer> TabAtkins: That's reasonable, and it points to a larger use case which is the ability to trigger an animation on a transition starting
<emeyer> …That seems generically useful for several cases and would avoid needing new properties
<emeyer> fantasai: Making that happen would let you control the flip point, but it won't give you the ability to animate things like color without JS
<astearns> ack fantasai
<emeyer> TabAtkins: Correct; doing more would require other things, but this seems like a big enough request for us to do
<futhark> q+
<emeyer> …I've thought about ways to trigger state properties and would be willing to defer animation in order to consider that, but I could see us doing this for properties now and considering the generic solution later
<astearns> ack futhark
<emeyer> futhark: Isn't this quite simlar to the overlay property for popovers?
<emeyer> TabAtkins: The reason we mess with the overlay state is so it stays consistent across things that can't be described in the CSS
<emeyer> TabAtkins: Did we just trigger off a DOM state?
<emeyer> futhark: Yeah, but we don't have that possibility here
<kizu> q+
<emeyer> TabAtkins: I could go dig up my old notes, but do we want to defer this for a little while to make a more informed decision?
<astearns> ack kizu
<emeyer> kizu: I think we can defer
<bramus> q+
<astearns> ack bramus
<emeyer> bramus: Want to mention that a lot of authors have been aasking to trigger view transitions on a state change, such as clicking on an input
<khush> q+
<emeyer> TabAtkins: Good point - we might be able to rely on subscribing to a transition, but that might be a frame delay
<astearns> ack khush
<emeyer> khush: Since you said it's a state transition, I was thinking of exposing it as a pseudo-class
<emeyer> …The only thing is, you dn't want anyone to put in a position change
<emeyer> TabAtkins: We can't generally do an allow/block list due to circular references, but you can certainly already cause those with :hover
<emeyer> …We consider that acceptable, so it would probably be okay to not restrict and assume authors won't do things that make the experience awful for their users
<emeyer> astearns: Sounds like we're going to defer for now, evaluate a more general solution, and decide if the general solution can be implemented in time
<emeyer> TabAtkins: Should we resolve to do this and leave them open as hooks for later?
<emeyer> fantasai: I think that's a good idea, but I'd want to ensure that will work with inheritance
<astearns> s/this/visibility/
<TabAtkins> s/do this/do the visibility:strongly-hidden thing/
<emeyer> …Probably want a better word than strongly hidden
<emeyer> TabAtkins: That sounds reasonable
<emeyer> TabAtkins: Proposing that when position visibility hides something, it does so by causing the visibility property to compute to a new forced-hidden value
<ydaniv> q+
<fantasai> "Making an element strongly hidden makes it act as if it and all of its descendants were visibility: hidden, regardless of what their actual visibility value is."
<astearns> ack ydaniv
<emeyer> astearns: My question is: can authors use this forced-hidden value?
<fantasai> s/forced-hidden/force-hidden/
<fantasai> s/forced-hidden/force-hidden/
<kbabbitt> q+
<emeyer> ydaniv: If we have a value, we could do it with container style queries, right?
<astearns> ack kbabbitt
<emeyer> TabAtkins: Yes. I'm not super familiar with the limitations on style queries but it should still be available
<emeyer> kbabbitt: What's the interaction between this and !important on a descendant
<fantasai> container style queries query the parent of the element you're styling, so it's not quite ideal, but could do some stuff with it
<emeyer> TabAtkins: If your ancestor is force-hidden, you're force-hidden
<emeyer> …It's a display: none without blowing away the boxes
<emeyer> …So they still take up the space
<emeyer> fantasai: We might want a value that keeps the boxes but doesn't display them
<emeyer> TabAtkins: Maybe
<fantasai> s/might/might also/
<emeyer> astearns: Anyone who would prefer to wait and digest before resolving?
<fantasai> s/doesn't display them/takes them out of flow/
<fantasai> s/of flow/of flow while not displaying them (more similar effect to display:none)/
<astearns> Proposing that when position visibility hides something, it does so by causing the visibility property to compute to a new forced-hidden value
<fantasai> "force-hidden"
<emeyer> astearns: RESOLVED: when position visibility hides something, it does so by causing the visibility property to compute to a new force-hidden value
<emeyer> RESOLVED: when position visibility hides something, it does so by causing the visibility property to compute to a new force-hidden value