How can I implement custom animation effects using @keyframes in Material UI?

While I have grasped the concept of using CSS animations with @keyframe, I am now eager to create custom animation code for my React project that utilizes Material UI. My main hurdle lies in figuring out how to write JavaScript code to personalize my animations using makeStyle() in Material UI.

This time, my goal is to customize the transition processes by percentages within Material UI. I want to implement code similar to this within the makeStyle() function:

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

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

Answer №1

An illustration showcasing the usage of keyframes syntax within the makeStyles function is provided below:

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);

https://codesandbox.io/s/keyframes-zmqns?fontsize=14&hidenavigation=1&theme=dark

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


Individuals transitioning to Material-UI v5 seeking guidance on executing this using Emotion rather than makeStyles, can refer to the following example demonstrating an alternate method utilizing Emotion for equivalent styles.

/** @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);

https://codesandbox.io/s/keyframes-emotion-2xm2r?fontsize=14&hidenavigation=1&theme=dark

Emotion keyframes reference:

Answer №2

New Features in Material UI Version 5

With the latest version, v5, you now have the ability to utilize the keyframes function from emotion (re-exported by default) to create keyframe styles:

import { styled } from '@mui/material/styles';
import { keyframes } from '@mui/system';

const spin = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const RotatedBox = styled("div")({
  backgroundColor: "pink",
  width: 30,
  height: 30,
  animation: `${spin} 1s infinite ease`
});

Since both styled and sx prop internally use emotion, you can apply the same style object to the sx prop as well:

<Box
  sx={{
    backgroundColor: "pink",
    width: 30,
    height: 30,
    animation: `${spin} 1s infinite ease`
  }}
/>

Material UI Version 4 Notes

Adding on to a previous answer, if you define the keyframe using makeStyles, ensure to prefix the animation name with "$". This small detail is crucial for the code to work correctly:

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"

If the keyframe is defined in the global scope, there is no need for the prefix:

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
  }
});

Stay updated with the discussion around this topic by following the relevant github issue.

Answer №3

This question has been resolved with excellent and helpful responses. I wanted to add that utilizing the sx prop in MUI can be quite beneficial:

<Typography
    sx={{
         "@keyframes slideInFromRight": {
            "0%": {
              opacity: 0,
              transform: "translateX(50px)",
                    },
           "100%": {
              opacity: 0.65,
              transform: "translateX(0)",
                    },
                  },
         animation: "slideInFromRight 0.6s ease-out forwards",
                }}
              >
  Some text
</Typography>

This feature allows for quick and easy styling of specific components directly within your code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining various font files under a single @font-face declaration

Here is the code snippet I'm currently working with: @font-face { font-family: 'icomoon'; src:url('../fonts/icons/icomoon.eot?2hq9os'); src:url('../fonts/icons/icomoon.eot?#iefix2hq9os') format('embedded-opent ...

Center an image vertically in an AdminLte content-wrapper division

I am currently utilizing an AdminLte template as the framework for my design. In the designated area where I need to insert the main content, it is structured in the following manner: <div class="content-wrapper"> <se ...

What is the best method for storing and accessing audio files that users upload in my MERN application?

I am developing a MERN application and am looking to implement a feature that allows users to upload audio files. I have read that storing the files directly in the database or within a folder inside the app is not recommended. I need a solution that en ...

Showing a collection of objects in a React component

**Recently started learning React and Node, and decided to fetch data into a functional component by following various tutorials. I successfully set up the server, connected it to the database, and fetched the data in React as per the tutorial instruction ...

What is the best way to choose alternate div class elements using only CSS without any javascript?

While I have experience using javascript and php to achieve a certain effect, I am now curious about the possibility of achieving the same effect solely with css. In my current project, I have a container that houses multiple items. Each item consists of ...

Image input not working in Internet Explorer

While the button displays correctly in Chrome and Firefox, it appears differently in IE: To address this issue in IE, you may need to make adjustments to the CSS styles specifically for that browser. One potential solution could involve creating a separat ...

Is there a way to identify the top five elements that are most frequently occurring in the array?

I've successfully found the element that appears the most in an array, but now I'm facing a new challenge where I need to identify the top 5 elements that appear most frequently. Here is the array: [ "fuji", "acros", &q ...

The css fails to display properly upon the page being reloaded using a button

While diving into the world of learning React JSX, I've encountered a perplexing issue. After clicking the load button, the page redirects correctly but the CSS styling I've implemented fails to display. Here is the HTML code snippet: <!DOCTY ...

What is the best method for positioning two forms in a vertical arrangement?

I'm looking to integrate a Login form in HTML within my C# project. Here's what I have so far: However, as you can see, the layout is not very aesthetically pleasing. I'm struggling to align the elements in a more visually appealing way. My ...

The .fill attribute in SVG seems to be having trouble functioning as intended

Could someone please clarify why I am unable to modify the fill of this svg: <div class="container"> <ul class="todo"> <li> This is an item <div class ="buttons"> <button class="remove"> <svg ...

The function this.props.array.map is not defined

Currently, I am in the process of learning React and have been attempting to display an element for each user in a predefined array. However, upon testing, my browser keeps throwing an error stating that this.props.users.map is not a function. I have imple ...

Activating event listener for the <datalist> element and enhancing the functionality of the <input> element in HTML5

Trying to utilize CSS to make the input box expand on hover/focus of the search ICON in CSS Attempting to call a function in HTML to an Angular component (seems like CSS cannot be used with datalist element) so that the input tag remains expanded when shi ...

Tips for showing just one table data cell (<td>) with identical class:

I'm facing a challenge with jQuery, HTML, and CSS. I'm currently in the process of designing a website for a railway company. The Home page is completed, but I've hit a roadblock on the tickets page. Using just HTML, CSS, and jQuery to build ...

Tips on incorporating toggle css classes on an element with a click event?

When working with Angular typescript instead of $scope, I am having trouble finding examples that don't involve $scope or JQuery. My goal is to create a clickable ellipsis that, when clicked, removes the overflow and text-overflow properties of a spec ...

When validated, the Yup.date() function seamlessly converts a date into a string without including the timezone

Currently, I am integrating Yup with react-hook-form and have defined the following schema in Yup: const validationSchema = Yup.object({ installation: Yup.string().nullable().required("Required"), from_date: Yup.date() .max(new Date(), "Can ...

The CSS file was not applied because the mime type did not match (Error code: SEC711

I am currently working on a JSP-Servlet application. I have successfully deployed the application using Eclipse with the default Tomcat 7 server. However, upon deployment, I noticed that the UI renders properly in Chrome and Firefox but encounters issues ...

What is the process of converting code to JavaScript and React?

There are two methods defined as shown below. const handleClick = React.useMemo(() => !isRunning ? (items: string | string[]) => { if(Array.isArray(items)){ startRun({ items: items }); } else ...

Using React Material Design UI with the Routing feature

Currently, I am in the process of developing a simple React application with the assistance of the Material-UI library. After utilizing the create-react-app example provided, I attempted to integrate Router into it for seamless navigation between compone ...

What are some top-notch 960.gs extensions for Firefox?

Currently, I am utilizing the 960.gs grid system for my website design work. Unfortunately, I have not been able to come across a high-quality 960.gs Firefox plugin. Can anyone recommend any good Firefox plugins that support 960.gs for web layout design? ...

Certain CSS classes are functioning properly, while others are not operating as expected

I am in the process of developing an ASP.Net page and utilizing Bootstrap, which has been functioning properly. Additionally, I have integrated a custom stylesheet to refine the appearance of the page. However, within the last couple of days, any new class ...