framer / motion

Open source, production-ready animation and gesture library for React
https://framer.com/motion
MIT License
23.39k stars 784 forks source link

[BUG] Next 13 /app page transition bug / flash + scrollbar layout shift #2250

Open Rover420 opened 1 year ago

Rover420 commented 1 year ago

Hi.

I have a code for NextJS page transition that was always working with /pages, but when I try to make this work with /app, there is a styling flash...

Version: "^10.13.0"

Basically there should be:

initial = opacity: 0 animate = opacity: 1

key={pathname}

but when I navigate between routes, there is instant initial opacity: 1 flash, then it disappear and animates again, every time with different delay etc. Even When I pass a huge delay to animate transition, there is still flash of opacity: 1

Something as below:

const Layout = ({ children }) => {

  const pathname = usePathname();

  return (
    <>
      <Navbar />
        <AnimatePresence initial={false} mode="wait" onExitComplete={() => window.scrollTo({ top: 0, left: 0, behavior: 'smooth'})}>
          <motion.div key={pathname} initial={{ opacity: 0 }} animate={{ opacity: 1, transition: { delay: 1 } }} exit={{ opacity: 0 }}>
            <AnimatePresence initial={true} mode="sync">
              <main id='main'>
                {children}
              </main>
            </AnimatePresence>
          </motion.div>
        </AnimatePresence>
      <PingComponent />
    </>
  )
}

export default Layout
Rover420 commented 1 year ago

Another issue is layout shift when scrollbar appears.

If there is transition between 100vh page and >100vh page, when scrollbar appears, pushes the content and animation is very weird.

I even got a custom scrollbar, with overflow: overlay in my project, but Chrome (and other Chrome based browsers like Brave) decided that overflow: overlay won't be supported so there is the issue.

On Opera with overflow: overlay there should be no issue with layout push, because it works and content is overflowing behind the scrollbar.

Rover420 commented 1 year ago

One possible fix for the layout shift I've just found is to set body width: 100vw and html overflow-x: hidden, but it's not very good approach obviously.

karamanliev commented 1 year ago

One possible fix for the layout shift I've just found is to set body width: 100vw and html overflow-x: hidden, but it's not very good approach obviously.

I have the same problem and this also does not work for me. If i set the width: 100vw and leave the horizontal scrollbar there's no layout shift anymore, but after I add overflow-x: hidden, the shift returns: https://github.com/framer/motion/issues/2246

j4jefferson commented 1 year ago

I am using this same approach for page transitions using nextjs template.jsx. Have found that exit transitions don't work. Would be nice to see this framer feature working again in nextjs 13.

OSAMA263 commented 8 months ago

you did put the initial={{ opacity: 0 }} on the motion.div but your also telling it to not use the initial value try and remove the prop initial={false} from the AnimatePresence