The short: I'm having trouble understanding Vue transition groups, the offical docs, recommended practice, and how to combine all that to get what I want.
What I want is a list of items that when new ones appear they transition from green to white and slide into the list. Then when they leave, they transition from red to white and slide out of the list.
If you want what I have so far, here's a js fiddle I made that was derived from the vue doc's list transition example. It's almost there, the only thing that isn't working is that the leaving items don't transition from red to grey.
Everything below is what I've researched to get to this point.
The official docs says I can apply transitions in .enter-active and .leave-active since they are applied throughout the entire animation.
v-enter-active: Active state for enter. Applied during the entire
entering phase. Added before element is inserted, removed when
transition/animation finishes. This class can be used to define the
duration, delay and easing curve for the entering transition.
v-leave-active: Active state for leave. Applied during the entire
leaving phase. Added immediately when leave transition is triggered,
removed when the transition/animation finishes. This class can be used
to define the duration, delay and easing curve for the leaving
transition.
And later, the List Transition docs applies the transition css statement to the element's own class instead of any of the transition classes automatically applied by vue. This makes some sense, as even the items that aren't actively leaving or entering still need to transition around those that get added or removed.
But then I stumbled upon this github post where a VueJs member described an issue with applying transitions in .active classes:
It's true that this behavior can be a bit confusing but it's actually working correctly because of the transition being applied but not being left enough time to change the color:
The .leave and .leave-active classes are applied at the same time. Because element already has a background-color, this triggers a 5s transition from grey to red, but one frame after the leave class is removed and leave-to is adding, triggering a new transition to green. So the color never gets enough time to change to red.
The solution is not applying the transition on leave-active but only on leave-to so the first change do not apply a transition: http://jsfiddle.net/posva/o4Lqw5ts/):
The problem do not appear on enter because the browser do not get the time to render the element without enter so it appears with the blue initial color and triggers the transition from there
Related
I have been trying to do a complex (for me at least) animation in react for a week and I am still unable to do it. I have attached the ss of a minimalist demo I made up in figma because I cannot share the actual design file.
I am using Next.js and I have to trigger this animation when the route changes (which happens automatically).
I have so far been using react-spring with its useTranslate hook. With this hook, I can use a state change to trigger the animation and also unmount the component at the end of it. For me the, automatic redirect happens after a state change that is coming from the backend via a subscription. I am hoping to use that to trigger the animation.
I am logically dividing this animation into two parts:
First part is the background gradient fading out along with the list while the avatars is fading in. This happens all the same time.
The cards duplicating behind it's back and slowly translating downwards and fading out.
So far I have figured out:
How to simultaneously trigger the animations. This is easy as I can pass the same state to different useTranslate hook with the same config object and the animations can be triggered at the same time and lasted the same duration.
How to trigger the opacity animation which can fade the avatars in while fading out the list.
But I am yet to figure out how:
To fade out background like that.
Duplicate the cards one behind another and then slowly translating them down. Not sure how to target each individual cards either.
Actually chain these animations so I can trigger the second one after the first.
Has anyone ever dealt with these kind of situations? Any other option than react-spring? Is it possible or easier if I use SVGs? Any piece of advice would be great.
Link to ss
I have a div and I want it to make a transition from font-size 20px to font-size 40px and also change its color. I know I can make this with maaany other alternativas, but I want to explore the usage of "transition" and I think something is wrong.
If I do this:
$("#xxx").css({transition:"all 1500ms ease-out 0ms",color:"#00FFFF", fontSize:"40px"});
The jQuery should first set the "transition", and after that set the color and font-size AND THE BROWSER should make the transition. But it's not the case, the font-size and color are applied immediatly.
What is even strange is that if I first set the transition and after 2 seconds set the font-size and color, then the transition will happen smoothly. Why?
Check the example below. If you open the link the browser will apply the color and font-size immediatly, instead of making the transition smootly. Why?
https://jsfiddle.net/hw33bghm/
The reason why this isn't behaving in the way that you expect is due to how reflow works in the DOM. Reflow is the web browser process for re-calculating the positions and geometries of elements in the DOM, and can be triggered by many things, including in this case, adjusting the CSS properties of an element.
When you make the $("#xxx").css({...}); call with multiple CSS properties you are giving the browser a batch of layout operations to perform and it will perform all of them in a user-blocking manner. Your styles are being applied immediately because there is no transition property until the operation is done and your new DOM is rendered.
Further, all modern browsers have optimizations to minimize reflow (again, it's a blocking operation and as such can affect performance), so if you simply separated setting your properties:
$("#xxx").css({transition:"all 1500ms ease-out 0ms"});
$("#xxx").css({color:"#00FFFF", fontSize:"40px"});
You might expect it to set the transition property, reflow, then set the color and fontSize, triggering the transition and working the way you intended. It won't though, those operations will be batched by the browser and again everything will happen in a single reflow.
This is also why it does work when you wait a second before setting the color and fontSize. Those layout operations are no longer batched together and so this time you have a transition property when the CSS for the other two are set.
For a little more information check out: https://developers.google.com/speed/articles/reflow#guidelines
I understand and use both transitions and animations, but it seems to me that there is a bit of a "hitch" as it were when trying to combine them. For example if you have an animation style that ends on a color, and sets the value indefinitely with -webkit-animation-fill-mode: forwards; it would make a lot of sense if I could smoothly transition from this state to another one if an overriding style could be set.
See jsfiddle. Note that toggling the yellow style uses the transition smoothly, but the use of animation can only smooth the initial 0-50% during the animation. There is no way to recover the final green state to either plain white or yellow background without an abrupt instant change that occurs when the animation value is unset. Note also that the animation, when active, completely overrides the !important style.
I don't know how much of this behavior is specified in the spec/WD/etc., but as far as I'm concerned this type of limiting behavior makes CSS animations next to worthless, and the animation would be advisable to perform step-wise from javascript, used with transitions. The downside to that is the greatly added overhead of doing it that way.
And to address the "unclear what I'm asking" vote, what I'm asking is how can I make an animation that can interpolate back out of the final animation state?
True, but have you tried use the value reverse in the animation-direction property for your animation?
I have a script that applies certain css styles to an element, then adds a transition style to the element, and then applies another css style to that element. What I'm trying to do is have the element get styles applied to it instantly, and then animate the next change. The code is basic, just set styles, then set transition styles, then set the final styles. But I'm experiencing that the first property being changed (the one without the transition) is having a transition applied to it, even though I do not set the transition property until afterwards. I have double checked that the element does not already have a transition property applied to it. Why is this?
Also, If I leave a 50 millisecond delay between applying the first styles and the transition, it works as expected.
You have to force a relayout after the first styles are applied (so they are processed without transitions) and then you can apply the styles that lead to a transition. The way you are doing it now, all the opeartions are being collapsed into one operation and thus everything is undergoing the transitions.
The simplest way to get the relayout is to apply the first CSS properties, then do a setTimeout(fn, 1) to apply the second set of properties in the timer callback. There are also other ways to force a relayout by requesting certain properties that trigger a relayout. I don't remember exactly which properties those are off the top of my head (would take some research).
I haven't tried this myself, but I think requesting a size property on your element such as .offsetHeight will force the relayout. The browser realizes that there are pending style changes and that those pending style changes might affect the size request so it does a relayout synchronously before returning the .offsetHeight value, thus solving your issue.
A somewhat similar question and answer: "Force Reflow" in CSS transitions in Bootstrap
I have a CSS3 position transition that makes a dive slide from one side to another when called by a JavaScript function (the function changes the value of style element "left"). This works great, but the CSS-transition also reacts to when a window is zoomed or resized, causing the div to appear in a faulty position for a second, before it transitions back to place.
Is there any way to only make it react only to my function, or do I have to do it the old fashion way, making a JavaScript transition?
Edit: You can find my code here: http://jsfiddle.net/PURFp/
You can add the transition property right before you start the animation and remove it after the animation has ended. Here's a demo : http://jsfiddle.net/PURFp/2/.