Styled-jsx styling not applied to Framer-Motion element

Viewed 819

I think I'm loosing my mind.

I created a new Nextjs project, installed Framer-Motion via NPM, ran the project in dev mode. Everything compiles and the page loads, but as soon as I add motion to an element, it vanishes with no errors.

I'm getting this both on PC and Mac. I even deleted my node modules and package.lock files and rolled back to a version of Next.js & framer-motion that I've had working in the past but it didn't do the trick. Just for kicks I created a new react app with framer-motion and it worked without issue there.

import {motion} from 'framer-motion';

export default function Home() {
  return (
    <>
      <motion.div
        className="test"
        animate={{ scale: 1.5 }}
      />
      <style jsx>{`
        .test {
          width: 100px;
          height: 100px;
          background-color: red;
        }
      `}</style>
    </>
  )
}
2 Answers

That's because your styled-jsx styles are not being applied to the framer-motion element.

To style a third-party component like the motion.div element you'll need to use the resolve tag from styled-jsx/css.

import { motion } from 'framer-motion';
import css from 'styled-jsx/css';

const { className, styles } = css.resolve`
  div {
    width: 100px;
    height: 100px;
    background: red;
  }
`;

export default function Home() {
    return (
        <>
            <motion.div
                className={className}
                animate={{ scale: 1.5 }}
            />
            {styles}
        </>
    )
}

I find this css.resolve thing extremelly cumbersome to apply afterwards.
Here's another way that works most of the time. The caveat is that it will get applied to all child components with the same .test class. (Just add another parent when necessary)

import {motion} from 'framer-motion';

export default function Home() {
  return (
    <div className="test-parent">
      <motion.div
        className="test"
        animate={{ scale: 1.5 }}
      />
      <style jsx>{`
        .test-parent :global(.test) {
          width: 100px;
          height: 100px;
          background-color: red;
        }
      `}</style>
    </div>
  )
}
Related