How to apply custom animation effect @keyframes in MaterialUI using makestyles() How to apply custom animation effect @keyframes in MaterialUI using makestyles() reactjs reactjs

How to apply custom animation effect @keyframes in MaterialUI using makestyles()


Here is an example demonstrating the keyframes syntax within makeStyles:

import React from "react";import ReactDOM from "react-dom";import { makeStyles } from "@material-ui/core/styles";import Button from "@material-ui/core/Button";import clsx from "clsx";const useStyles = makeStyles(theme => ({  animatedItem: {    animation: `$myEffect 3000ms ${theme.transitions.easing.easeInOut}`  },  animatedItemExiting: {    animation: `$myEffectExit 3000ms ${theme.transitions.easing.easeInOut}`,    opacity: 0,    transform: "translateY(-200%)"  },  "@keyframes myEffect": {    "0%": {      opacity: 0,      transform: "translateY(-200%)"    },    "100%": {      opacity: 1,      transform: "translateY(0)"    }  },  "@keyframes myEffectExit": {    "0%": {      opacity: 1,      transform: "translateY(0)"    },    "100%": {      opacity: 0,      transform: "translateY(-200%)"    }  }}));function App() {  const classes = useStyles();  const [exit, setExit] = React.useState(false);  return (    <>      <div        className={clsx(classes.animatedItem, {          [classes.animatedItemExiting]: exit        })}      >        <h1>Hello CodeSandbox</h1>        <h2>Start editing to see some magic happen!</h2>        <Button onClick={() => setExit(true)}>Click to exit</Button>      </div>      {exit && <Button onClick={() => setExit(false)}>Click to enter</Button>}    </>  );}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);

Edit keyframes

Documentation: https://cssinjs.org/jss-syntax/?v=v10.0.0#keyframes-animation


For those who have started using Material-UI v5 and want to know how to do this using Emotion rather than makeStyles, below is an example of one way to do the equivalent styles using Emotion.

/** @jsxImportSource @emotion/react */import React from "react";import ReactDOM from "react-dom";import { css, keyframes } from "@emotion/react";import { useTheme } from "@material-ui/core/styles";import Button from "@material-ui/core/Button";const myEffect = keyframes`  0% {    opacity: 0;    transform: translateY(-200%);  }  100% {    opacity: 1;    transform: translateY(0);  }`;const myEffectExit = keyframes`  0% {    opacity: 1;    transform: translateY(0);  }  100% {    opacity: 0;    transform: translateY(-200%);  }`;function App() {  const theme = useTheme();  const animatedItem = css`    animation: ${myEffect} 3000ms ${theme.transitions.easing.easeInOut};  `;  const animatedItemExiting = css`    animation: ${myEffectExit} 3000ms ${theme.transitions.easing.easeInOut};    opacity: 0;    transform: translateY(-200%);  `;  const [exit, setExit] = React.useState(false);  return (    <>      <div css={exit ? animatedItemExiting : animatedItem}>        <h1>Hello CodeSandbox</h1>        <h2>Start editing to see some magic happen!</h2>        <Button onClick={() => setExit(true)}>Click to exit</Button>      </div>      {exit && <Button onClick={() => setExit(false)}>Click to enter</Button>}    </>  );}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);

Edit keyframes emotion

Emotion keyframes documentation: https://emotion.sh/docs/keyframes


Just some notes on top of @Ryan's answer. If you define the keyframe using makeStyles. Remember to prefix the animation name with $. I missed this small detail the first time and my code didn't work, in the example below

const useStyles = makeStyles({  "@keyframes fadeIn": {    "0%": {      opacity: 0,      transform: "translateY(5rem)"    },    "100%": {      opacity: 1,      transform: "translateY(0)"    }  },  selector: {    animation: "$fadeIn .2s ease-in-out"  }});

Instead of

animation: "fadeIn .2s ease-in-out"

It should be

animation: "$fadeIn .2s ease-in-out"

But if you define the keyframe in global scope. The prefix is unnecessary here

const useStyles = makeStyles({  "@global": {    "@keyframes fadeIn": {      "0%": {        opacity: 0,        transform: "translateY(5rem)"      },      "100%": {        opacity: 1,        transform: "translateY(0)"      }    }  },  selector: {    animation: "fadeIn .2s ease-in-out" // --> this works  }});

Follow this issue on github for more discussion about this.