cssreactjsmaterial-uijss

How to apply custom animation effect @keyframes in Material UI?


I have learned to use animation in CSS using @keyframe. I however want to write custom animation code for my React project (using Material UI). My challenge is how I can write the Javascript code to customize my animations using makeStyle() in Material UI.

I want to be able to customize the transition processes in percentages this time around in Material UI. I need to write code like this in makeStyle() but I don't understand how to:

@keyframes myEffect {
 0%{
  opacity:0;
  transform: translateY(-200%); 
 }

100% {
  opacity:1;
  transform: translateY(0);
 }
}

Solution

  • 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 "@mui/material/styles";
    import Button from "@mui/material/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