Search code examples
javascriptcssreactjscss-transformsreact-spring

Prevent Scrollbar Appearing on transform: translate with React-Spring


Whenever I add a translate() CSS function to a react-spring useTransition hook from or leave property where the element will go out of the viewport, I am getting a vertical/horizontal scrollbar.

const transitions = useTransition(show, null, {
    from: {
        opacity: 0,
        transform: "translate3d(500px,0px,0px) scale(1)"
    },
    enter: {
        opacity: 1,
        transform: "translate3d(0px,0px,0px) scale(1)"
    },
    leave: {
        opacity: 0,
        transform: "translate3d(0px,-500px,0px) scale(1)"
    },
    config: {
        duration: 3000
    }
});

enter image description here

I know this is expected and the general solution is to add overflow: hidden to the body.

But I am unsure how to do this while the animation is occurring? As I don't want to add overflow: hidden to the body at all times as I do need access to the scrollbar in certain pages, just not when the animation has initiated?

Here is a CodeSandbox to try it out for yourselves

Any help would be greatly appreciated.


Solution

  • You can change the class of the body with document.body.classList.add and remove. For example you can add one more useEffect, like this:

      useEffect(() => {
        if (show) {
          document.body.classList.add("animation");
        } else {
          document.body.classList.remove("animation");
        }
      }, [show]);
    

    And of course you must define your style to the class:

    .animation {
      overflow: hidden;
    }
    

    See the example here. https://codesandbox.io/s/react-spring-scroll-fj6t8

    It is just a crude example. You can add the classList.remove to the return of the useEffect. Or you can try adding it to the onRest callback of useTransition if you want to remove it when the animation stopped.