CSS module styling is removed too early on route changes
Problem
Bug report Describe the bug CSS module styling is removed immediately after clicking a `next/link`, instead of after the DOM is removed on production builds. This causes the components to have no styling at all during a page transition. This issue does not happen on dev mode. I believe this is a bug with CSS modules specifically because components styled with `styled-jsx` don't have this problem. Really would love to be able to use Sass via CSS modules here instead of re-writing the entire app I'm working on using `styled-jsx`. If Sass modules can't work in this scenario, I think I would be forced to use `styled-jsx`, which is not my preferred method of styling my components for this project. To Reproduce I have created repos, and deployed these repos to demonstrate the problem using framer-motion for page transitions. If you were to pull these repos and run them locally using `npm run dev`, you will see that the flash of unstyled content does not happen on any one of them in dev mode. However, on their deployed sites, you can see the flash of unstyled content with CSS modules and Sass modules. styled-jsx Behavior: correct, no flash of unstyled content Deployed site on Vercel Repo CSS modules Behavior: buggy, there is a flash of unstyled content immediately after clicking the link Deployed site on Vercel Repo Sass via CSS modules (additional) Behavior: buggy, there is a flash of unstyled content immediately after clicking the link (same as CSS modules) Deployed
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Fix Flash of Unstyled Content in CSS Modules on Route Changes
The flash of unstyled content occurs because CSS modules are removed from the DOM too early during the transition between pages in production builds. This is likely due to the way Next.js handles CSS module loading and unloading, which differs from the behavior observed in development mode. The immediate removal of styles before the new page is fully rendered leads to unstyled components during the transition.
Awaiting Verification
Be the first to verify this fix
- 1
Update Next.js Version
Ensure you are using the latest stable version of Next.js, as updates often include bug fixes and improvements related to CSS handling.
bashnpm install next@latest - 2
Implement CSS Transition Classes
Add transition classes to your components that will maintain styling during the transition. Use a CSS class to apply styles until the new page is fully loaded.
css.fade-enter { opacity: 0; } .fade-enter-active { opacity: 1; transition: opacity 300ms; } .fade-exit { opacity: 1; } .fade-exit-active { opacity: 0; transition: opacity 300ms; } - 3
Modify Link Component
Wrap your `next/link` components with a transition wrapper that applies the CSS transition classes during the page change. This will help mitigate the flash of unstyled content.
javascriptimport { motion } from 'framer-motion'; <motion.div initial='fade-enter' animate='fade-enter-active' exit='fade-exit' transition={{ duration: 0.3 }}> <Link href='/next-page'>Next Page</Link> </motion.div> - 4
Test in Production Mode
Run your application in production mode to verify that the flash of unstyled content is resolved. Use `npm run build` followed by `npm start` to simulate the production environment.
bashnpm run build && npm start
Validation
Confirm that the flash of unstyled content no longer occurs by navigating between pages in the deployed application. The styles should remain consistent throughout the transition, and no unstyled components should be visible.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep