How to Fix Visibility Issues With Page Transition Animations When JavaScript Is Disabled (Remix SSR)
A page transition animation is often implemented as a CSS transformation where the content is initially made invisible or pushed off-screen and finally animated to its visible state. This, however, poses problems when JavaScript is disabled because the animation never takes place so the elements remain invisible or askew.
For example, you might have a Framer Motion animation like this:
<motion.div
initial={{
opacity: 0,
translateY: '100px',
}}
animate={{
opacity: 1,
translateY: 0,
}}
transition={{
duration: 0.4,
}}
>
<h1>Hello!</h1>
</motion.div>
Which means that if JavaScript is disabled, the page is rendered server-side only and the browser never loads or runs the script that triggers the animation. The div element will always have the initial opacity of zero and translate-y value of 100px.
To fix this visibility issue, we can add a noscript tag to the head of the HTML document to ignore all opacity and transform styles when client-side JavaScript is not available:
<noscript>
<style dangerouslySetInnerHTML={{
__html: '[style*="opacity:0"] { opacity: unset !important; transform: unset !important; }',
}} />
</noscript>
This establishes a global CSS rule that unsets all opacity and transform properties when JavaScript is disabled. Please note that this applies to all such styles, so if your CSS relies on opacity or transform elsewhere, you should declare a more specific selector that targets visibility animations only.