joshwcomeau / react-flip-move

Effortless animation between DOM changes (eg. list reordering) using the FLIP technique.
http://joshwcomeau.github.io/react-flip-move/examples
MIT License
4.08k stars 259 forks source link

Text not appearing at the end of animation #205

Closed ioRekz closed 6 years ago

ioRekz commented 6 years ago

Here is a video clip showing the problem. https://drive.google.com/uc?id=1FKYxAF4bBVoDPOBqelfyPZOYiKh_oTMa

I'm using the accordion animation. I have the same problem for all the provided animations except "Fade".

This is working correctly on firefox and I'm pretty sure it was working ok on previous chrome version. I couldn't replicate the bug on codesandbox or something like this so this must be a combination of my code + browser.

Based on the fact that only Fade is working, would you have ideas or things I could try ?

Here are the css properties on the element :

    align-items: center;
    background-color: transparent;
    border-radius: 0px;
    border-color: rgb(221, 221, 221);
    border-style: solid;
    border-width: 0px;
    color: rgb(228, 228, 228);
    font-family: Roboto;
    font-size: 31.4596px;
    font-style: normal;
    font-weight: 400;
    height: 48.6971px;
    letter-spacing: 2px;
    line-height: 1.2;
    min-height: 20px;
    min-width: 20px;
    opacity: 1;
    perspective: 147.467px;
    text-align: right;
    transform-origin: 50% 50% 0px;
    width: 215.349px;
    position: relative;
    user-select: none;
    display: flex;
    justify-content: flex-end;
    transform: perspective(147.467px) rotate(0deg) rotateX(0deg) rotateY(0deg) skewX(0deg) skewY(0deg);
joshwcomeau commented 6 years ago

Hey there! Thanks for the video, really helpful to get a sense of the problem.

Sadly, I don't really know what the root cause of this issue is; seems like you need to force a repaint to get the browser to show the text, which is super strange. I'm guessing it's some quirk with perspective, and the combination of different CSS transitions affecting it (FlipMove has its own, presumably on that empty parent <div>)

Some stuff to try, to help us understand the issue:

1) Can we isolate the issue to a specific CSS property? What happens if you remove the perspective, or align-items prop? Try all of 'em and see if 1 in particular is the problem.

2) What happens if you put the text in a style-free <div> inside that one?

3) Why is the font-size 31.4596px? What happens if you set it to a round number like 32px? Is it dynamically animated?

Because it seems like the issue is solved with a repaint, I have a hacky potential solution for you: You just need to force a repaint when the animation is complete. So you could do something like this:

<FlipMove
  onFinish={(elem, domNode) => domNode.focus()}
/>

(According to this StackOverflow thread, this is an easy way to get Chrome to repaint an element. You can also try the other, more verbose solutions in that thread)

This is obviously not a "nice" solution, but if we can't get to the bottom of the real issue, might be a fine band-aid.

ioRekz commented 6 years ago

Thanks for the detailed answer, that really helped me ! And good guess with the perspective ! To defend my self a little bit, I tried with and without it before but perspective was added with the perspective css property but can also be used inside transform: perspective which I didn't remove on my first tests.

My code will break for blocks with animations + perspective for now but it's quite rare that users use both. I'll try to look if I find something that can fix this. I hope I won't have to use the repaint solution but I'll reconsider if I don't find anything.

Thanks again and if you have any other ideas now that we know perspective is at the origin. Could this be related with #196