cssreactjsnext.jscss-modulesanimate.css

Not able to access the animate.css's animation keyframe names from scss file


I'm trying to use animate.css with React/Next.js. I can create animations using animate.css's inline class names, but I want to call animate.css's keyframe animations from my scss file. I was following a youtube guide and he was able to do it. The only difference is that I'm using Next.js.

As a reference:

https://www.youtube.com/watch?v=ESHaail1eGc&t=4379s&ab_channel=CodewithSloba

He imports the animate.css file at 3:55 and and is able to use animate.css's bounceIn animation at 38:31.

Example:

In my styles/globals.scss file, I added animate.css

@import 'animate.css'

In my AnimateLetters.tsx file, at the top I import the scss module,

import styles from '../../styles/AnimatedLetters.module.scss'

In the same file and inside the React component,

This works for me:

<span className='animate__animated animated__bounceIn'> H </span>

But this doesn't:

<span className={styles.animateText}> H </span>

In my AnimatedLetters.module.scss, I have

.animateText {
  display: inline-block;
  animation-name: bounceIn;
  animation-duration: 2s
}

A hacky way of getting by this is finding the keyframe inside the node_modules/animate.css/animate.css file and then copying it into my scss file, like below:

@keyframes bounceIn {
  from,
  20%,
  40%,
  60%,
  80%,
  to {
    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
  }

  0% {
    opacity: 0;
    -webkit-transform: scale3d(0.3, 0.3, 0.3);
    transform: scale3d(0.3, 0.3, 0.3);
  }

  20% {
    -webkit-transform: scale3d(1.1, 1.1, 1.1);
    transform: scale3d(1.1, 1.1, 1.1);
  }

  40% {
    -webkit-transform: scale3d(0.9, 0.9, 0.9);
    transform: scale3d(0.9, 0.9, 0.9);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(1.03, 1.03, 1.03);
    transform: scale3d(1.03, 1.03, 1.03);
  }

  80% {
    -webkit-transform: scale3d(0.97, 0.97, 0.97);
    transform: scale3d(0.97, 0.97, 0.97);
  }

  to {
    opacity: 1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}

I would prefer not to have to do this. Also, if I do resort to this, would it be best just to uninstall animate.css and just copy the keyframes I'm using into my global.scss?


Solution

  • Since the bounceIn animation is declared globally (i.e. imported from animate.css in your globals.scss), you have to use the :global selector when using it in your Sass Modules file. Otherwise, Sass Modules assumes bounceIn is locally scoped and will hash the animation name.

    .animateText :global {
        display: inline-block;
        animation-name: bounceIn;
        animation-duration: 2s
    }
    
    /* or */
    
    .animateText {
        display: inline-block;
        animation-duration: 2s
        &:global {
            animation-name: bounceIn;
        }
    }
    

    By default, CSS Modules assumes everything is locally scoped. If you want to access anything that's globally scoped you have to use :global.