Documentation

Documentation

Animating with Tailwind CSS

Motion is the perfect animation companion for Tailwind CSS v4. In this guide, we'll learn how to:

  • Perform basic animations with the two libraries.

  • Create responsive animations by animating CSS variables.

  • Generate Tailwind CSS spring animations directly in your code editor using Motion for AI.

Basic animations

The key to using Motion with Tailwind CSS is to let each library do what it does best.

  • Tailwind CSS's utility classes for static and responsive styling.

  • Motion's animation props like animate and layout for animation.

Motion animates by applying inline styles, or via native browser animations - both of which override Tailwind CSS classes. This separation is partly why the two work so well together.

Here's a basic example of a button with a hover effect. Tailwind styles the button, while Motion handles the interactivity.

import { motion } from "motion/react";

function Button() {
  return (
    <motion.button
      className="px-6 py-3 bg-indigo-600 text-white font-semibold rounded-lg shadow-lg"
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
    >
      Click Me!
    </motion.button>
  );
}

Responsive animations

It's possible to make an animation responsive to screen size by combining Tailwind CSS's ability to set responsive CSS variables together with Motion's ability to animate those variables.

To start, we can define our initial values like so:

<motion.div
  className="
    p-8 bg-rose-500 text-white rounded-xl shadow-lg max-w-md mx-auto
    
    /* Define the CSS variable inline, with responsive values */
    [--entry-distance-y:20px] 
    md:[--entry-distance-y:50px]
  "
  initial={{ opacity: 0, y: "var(--entry-distance-y)" }}

Here, on medium screens and above, the initial y value will be 50px, whereas on smaller screens it'll be 20px.

Then, we can set animate to animate y to 0 from this responsive start value.

animate={{ opacity: 1, y: 0 }}

It's possible to animate to and/or from a CSS variable, so it's equally possible to animate to a responsive value, or between responsive values.

Generate CSS springs

CSS is capable of performing spring animations using the linear() easing function, so you can perform simple spring animations without including Motion into your bundle. The downside of linear() is its obscure syntax that makes it impossible to write or edit without a generator of some kind.

With Motion for AI, it's possible to generate CSS springs directly in your AI code editor. We can make these CSS springs reusable with Tailwind utility classes.

Once installed, we can use a prompt like "make a tailwind theme to generate a css spring utility class". You can ask for a specific spring, like a "slightly bouncy spring", or otherwise it'll default to a small selection of different-feeling springs:

@theme {
  --ease-spring-snappy: linear(0, 0.2375, 0.5904, 0.8358, 0.9599, 1.0061, 1.0152, 1.0116, 1.0062, 1.0025, 1.0006, 0.9999, 1);
  --ease-spring: linear(0, 0.0942, 0.2989, 0.5275, 0.73, 0.8839, 0.9858, 1.0425, 1.0655, 1.0666, 1.0558, 1.0405, 1.0255, 1.0131, 1.0043, 0.9989, 0.9962, 1);
  --ease-spring-soft: linear(0, 0.0332, 0.1241, 0.2583, 0.4207, 0.5967, 0.7729, 0.9379, 1.0826, 1.2006, 1.2883, 1.3445, 1.3701, 1.3679, 1.3423, 1.2983, 1.2415, 1.1774, 1.1113, 1.0477, 0.9904, 0.9421, 0.9047, 0.8789, 0.8648, 0.8615, 0.8677, 0.8815, 0.9009, 0.9239, 0.9485, 0.9727, 0.9952, 1.0146, 1.0303, 1.0417, 1.0487, 1.0515, 1.0506, 1.0465, 1.0401, 1.032, 1.023, 1.0138, 1.0051, 0.9974, 0.9909, 0.986, 0.9828, 0.9811, 0.9809, 0.9819, 0.984, 0.9868, 0.99, 0.9935, 0.9968, 0.9998, 1.0025, 1.0045, 1.006, 1.0069, 1.0072, 1.0069, 1.0063, 1.0054, 1.0042, 1.003, 1.0017, 1.0005, 0.9995, 0.9986, 0.998, 0.9976, 1);
}

This new spring easings can now be used via utility classes:

<div className="transition-transform duration-700 ease-spring-soft">

Alternatively, these easings can be combined with CSS keyframe animations:

@theme {
  --animate-slide-up: slide-up 700ms;
  
  @keyframes slide-up {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }

  /* Generated springs go here */
}
<div class="animate-slide-up ease-spring-soft">

Troubleshooting

My animation is moving weirdly

If you find that an Motion x Tailwind CSS animation is stuttery, or moving weirdly in some way, usually there's a conflict between the Motion animation and a pre-existing Tailwind transition class.

To fix, ensure that the element has no transition- class applied, for instance transition-all etc.

Motion is the perfect animation companion for Tailwind CSS v4. In this guide, we'll learn how to:

  • Perform basic animations with the two libraries.

  • Create responsive animations by animating CSS variables.

  • Generate Tailwind CSS spring animations directly in your code editor using Motion for AI.

Basic animations

The key to using Motion with Tailwind CSS is to let each library do what it does best.

  • Tailwind CSS's utility classes for static and responsive styling.

  • Motion's animation props like animate and layout for animation.

Motion animates by applying inline styles, or via native browser animations - both of which override Tailwind CSS classes. This separation is partly why the two work so well together.

Here's a basic example of a button with a hover effect. Tailwind styles the button, while Motion handles the interactivity.

import { motion } from "motion/react";

function Button() {
  return (
    <motion.button
      className="px-6 py-3 bg-indigo-600 text-white font-semibold rounded-lg shadow-lg"
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
    >
      Click Me!
    </motion.button>
  );
}

Responsive animations

It's possible to make an animation responsive to screen size by combining Tailwind CSS's ability to set responsive CSS variables together with Motion's ability to animate those variables.

To start, we can define our initial values like so:

<motion.div
  className="
    p-8 bg-rose-500 text-white rounded-xl shadow-lg max-w-md mx-auto
    
    /* Define the CSS variable inline, with responsive values */
    [--entry-distance-y:20px] 
    md:[--entry-distance-y:50px]
  "
  initial={{ opacity: 0, y: "var(--entry-distance-y)" }}

Here, on medium screens and above, the initial y value will be 50px, whereas on smaller screens it'll be 20px.

Then, we can set animate to animate y to 0 from this responsive start value.

animate={{ opacity: 1, y: 0 }}

It's possible to animate to and/or from a CSS variable, so it's equally possible to animate to a responsive value, or between responsive values.

Generate CSS springs

CSS is capable of performing spring animations using the linear() easing function, so you can perform simple spring animations without including Motion into your bundle. The downside of linear() is its obscure syntax that makes it impossible to write or edit without a generator of some kind.

With Motion for AI, it's possible to generate CSS springs directly in your AI code editor. We can make these CSS springs reusable with Tailwind utility classes.

Once installed, we can use a prompt like "make a tailwind theme to generate a css spring utility class". You can ask for a specific spring, like a "slightly bouncy spring", or otherwise it'll default to a small selection of different-feeling springs:

@theme {
  --ease-spring-snappy: linear(0, 0.2375, 0.5904, 0.8358, 0.9599, 1.0061, 1.0152, 1.0116, 1.0062, 1.0025, 1.0006, 0.9999, 1);
  --ease-spring: linear(0, 0.0942, 0.2989, 0.5275, 0.73, 0.8839, 0.9858, 1.0425, 1.0655, 1.0666, 1.0558, 1.0405, 1.0255, 1.0131, 1.0043, 0.9989, 0.9962, 1);
  --ease-spring-soft: linear(0, 0.0332, 0.1241, 0.2583, 0.4207, 0.5967, 0.7729, 0.9379, 1.0826, 1.2006, 1.2883, 1.3445, 1.3701, 1.3679, 1.3423, 1.2983, 1.2415, 1.1774, 1.1113, 1.0477, 0.9904, 0.9421, 0.9047, 0.8789, 0.8648, 0.8615, 0.8677, 0.8815, 0.9009, 0.9239, 0.9485, 0.9727, 0.9952, 1.0146, 1.0303, 1.0417, 1.0487, 1.0515, 1.0506, 1.0465, 1.0401, 1.032, 1.023, 1.0138, 1.0051, 0.9974, 0.9909, 0.986, 0.9828, 0.9811, 0.9809, 0.9819, 0.984, 0.9868, 0.99, 0.9935, 0.9968, 0.9998, 1.0025, 1.0045, 1.006, 1.0069, 1.0072, 1.0069, 1.0063, 1.0054, 1.0042, 1.003, 1.0017, 1.0005, 0.9995, 0.9986, 0.998, 0.9976, 1);
}

This new spring easings can now be used via utility classes:

<div className="transition-transform duration-700 ease-spring-soft">

Alternatively, these easings can be combined with CSS keyframe animations:

@theme {
  --animate-slide-up: slide-up 700ms;
  
  @keyframes slide-up {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }

  /* Generated springs go here */
}
<div class="animate-slide-up ease-spring-soft">

Troubleshooting

My animation is moving weirdly

If you find that an Motion x Tailwind CSS animation is stuttery, or moving weirdly in some way, usually there's a conflict between the Motion animation and a pre-existing Tailwind transition class.

To fix, ensure that the element has no transition- class applied, for instance transition-all etc.

Motion is the perfect animation companion for Tailwind CSS v4. In this guide, we'll learn how to:

  • Perform basic animations with the two libraries.

  • Create responsive animations by animating CSS variables.

  • Generate Tailwind CSS spring animations directly in your code editor using Motion for AI.

Basic animations

The key to using Motion with Tailwind CSS is to let each library do what it does best.

  • Tailwind CSS's utility classes for static and responsive styling.

  • Motion's animation props like animate and layout for animation.

Motion animates by applying inline styles, or via native browser animations - both of which override Tailwind CSS classes. This separation is partly why the two work so well together.

Here's a basic example of a button with a hover effect. Tailwind styles the button, while Motion handles the interactivity.

import { motion } from "motion/react";

function Button() {
  return (
    <motion.button
      className="px-6 py-3 bg-indigo-600 text-white font-semibold rounded-lg shadow-lg"
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
    >
      Click Me!
    </motion.button>
  );
}

Responsive animations

It's possible to make an animation responsive to screen size by combining Tailwind CSS's ability to set responsive CSS variables together with Motion's ability to animate those variables.

To start, we can define our initial values like so:

<motion.div
  className="
    p-8 bg-rose-500 text-white rounded-xl shadow-lg max-w-md mx-auto
    
    /* Define the CSS variable inline, with responsive values */
    [--entry-distance-y:20px] 
    md:[--entry-distance-y:50px]
  "
  initial={{ opacity: 0, y: "var(--entry-distance-y)" }}

Here, on medium screens and above, the initial y value will be 50px, whereas on smaller screens it'll be 20px.

Then, we can set animate to animate y to 0 from this responsive start value.

animate={{ opacity: 1, y: 0 }}

It's possible to animate to and/or from a CSS variable, so it's equally possible to animate to a responsive value, or between responsive values.

Generate CSS springs

CSS is capable of performing spring animations using the linear() easing function, so you can perform simple spring animations without including Motion into your bundle. The downside of linear() is its obscure syntax that makes it impossible to write or edit without a generator of some kind.

With Motion for AI, it's possible to generate CSS springs directly in your AI code editor. We can make these CSS springs reusable with Tailwind utility classes.

Once installed, we can use a prompt like "make a tailwind theme to generate a css spring utility class". You can ask for a specific spring, like a "slightly bouncy spring", or otherwise it'll default to a small selection of different-feeling springs:

@theme {
  --ease-spring-snappy: linear(0, 0.2375, 0.5904, 0.8358, 0.9599, 1.0061, 1.0152, 1.0116, 1.0062, 1.0025, 1.0006, 0.9999, 1);
  --ease-spring: linear(0, 0.0942, 0.2989, 0.5275, 0.73, 0.8839, 0.9858, 1.0425, 1.0655, 1.0666, 1.0558, 1.0405, 1.0255, 1.0131, 1.0043, 0.9989, 0.9962, 1);
  --ease-spring-soft: linear(0, 0.0332, 0.1241, 0.2583, 0.4207, 0.5967, 0.7729, 0.9379, 1.0826, 1.2006, 1.2883, 1.3445, 1.3701, 1.3679, 1.3423, 1.2983, 1.2415, 1.1774, 1.1113, 1.0477, 0.9904, 0.9421, 0.9047, 0.8789, 0.8648, 0.8615, 0.8677, 0.8815, 0.9009, 0.9239, 0.9485, 0.9727, 0.9952, 1.0146, 1.0303, 1.0417, 1.0487, 1.0515, 1.0506, 1.0465, 1.0401, 1.032, 1.023, 1.0138, 1.0051, 0.9974, 0.9909, 0.986, 0.9828, 0.9811, 0.9809, 0.9819, 0.984, 0.9868, 0.99, 0.9935, 0.9968, 0.9998, 1.0025, 1.0045, 1.006, 1.0069, 1.0072, 1.0069, 1.0063, 1.0054, 1.0042, 1.003, 1.0017, 1.0005, 0.9995, 0.9986, 0.998, 0.9976, 1);
}

This new spring easings can now be used via utility classes:

<div className="transition-transform duration-700 ease-spring-soft">

Alternatively, these easings can be combined with CSS keyframe animations:

@theme {
  --animate-slide-up: slide-up 700ms;
  
  @keyframes slide-up {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }

  /* Generated springs go here */
}
<div class="animate-slide-up ease-spring-soft">

Troubleshooting

My animation is moving weirdly

If you find that an Motion x Tailwind CSS animation is stuttery, or moving weirdly in some way, usually there's a conflict between the Motion animation and a pre-existing Tailwind transition class.

To fix, ensure that the element has no transition- class applied, for instance transition-all etc.

Level up your animations with Motion+

More than 180+ Motion examples, exclusive APIs like Cursor, private Discord and GitHub, and powerful VS Code animation editing tools.

One-time payment, lifetime updates.

Motion is supported by the best in the industry.

Stay in the loop

Subscribe for the latest news & updates.

Stay in the loop

Subscribe for the latest news & updates.