Create an Animated Scaling Button using Framer Motion (Motion for React)
Day 1/100 of my UI animation challenge

Search for a command to run...
Day 1/100 of my UI animation challenge

No comments yet. Be the first to comment.
You might need to ask yourself too

Let's talk about usability and 3 common mistakes you might be making when building that product. Confusing 'Account Setup' with 'Onboarding': Your onboarding flow is meant to serve a primary purpose,

Last year during Google's Built-In AI hackathon, I built an experimental Chrome extension called Clarity Lens. The product was inspired by thinking about the 'hidden 16%', the portion of the world's p

If you've used Youtube long enough, you'd realize it gradually became better in understanding your needs. I'm sure you can relate to this - you think of something, next thing, you open Youtube and it's being advertised, or you come across it on your ...

Trade-offs, accessibility concerns, and what CSS alone can’t solve

Difficulty: ⭐️ (1/5 stars)
Setup/Prerequisites: React.js, TailwindCSS, Framer Motion
Key Concepts: Using animate, whileHover, whileTap and variants in Framer Motion
Since today is day 1, I’m starting with a simple animation - a button that scales on hover and tap. This animation is quite simple but shows core Framer Motion concepts like variants and gesture animations.
Smooth scale animation on hover
Slight scale reduction on click/tap
Subtle shadow animation
Spring animation for natural movement
Some things you should take note of in these highlighted features are the italicized words and that’s because animations work best when they are used just in the right amount and in the right places - they should feel natural🤗
The button is created first before going on to implement the different states and adding animations.
The animation happens in three main steps:
Wrap the button component with a motion.div element instead of directly applying motion to the button element to separate it’s styling.
Identify the states. Looking at the key animation features, there are 3 defined states I could get. The buttonVariants object is where the states are defined:
initial: The button's default state and styling
hover: The state where the button scales up and adds shadow on hover
tap: In this state, the button slightly scales down when clicked/tapped
Specifying the transition type: This defines how the button changes from one state to another. Here I’m using the spring transition which creates a bouncy, natural feel. The other properties related to the ‘spring’ transition are also set to properly add the mild transition effect.
stiffness: 400 makes the animation “snap“
The value here usually ranges from 0 to 1000, with higher values making the animation more rigid, while lower values make it softer and slower.
damping: 10 This adds a slight bounce
For damping the value ranges from 0 to 100, with higher values make the animation settle faster, while lower values create more bounce.
import { motion } from "framer-motion";
export default function AnimatedButton() {
return (
<div className="flex min-h-screen items-center justify-center bg-gray-100">
<motion.div
variants={buttonVariants}
initial="initial"
whileHover="hover"
whileTap="tap"
>
<button className="bg-blue-500 px-6 py-2 text-white">
Hover Me
</button>
</motion.div>
</div>
);
}
In the buttonVariants object, the different states which have been previously identified are defined using the styling specific to each state.
💡Remember to use subtle shadows
const buttonVariants = {
initial: {
scale: 1,
boxShadow: "0px 0px 0px rgba(0,0,0,0.2)",
},
hover: {
scale: 1.1,
boxShadow: "0px 5px 15px rgba(0,0,0,0.2)",
transition: {
type: "spring",
stiffness: 400,
damping: 10
}
},
tap: {
scale: 0.95,
boxShadow: "0px 2px 5px rgba(0,0,0,0.2)",
}
};
Spring animations feel more natural than linear ones like for interface elements.
Small scale changes (like 0.95-1.1) are often more realistic.
Combining scale with mild shadow creates a great three-dimensional effect.
What animation ideas do you suggest I add to this button? I’m thinking of these:
Adding sound effects for interaction
Creating different variants for different button states (loading, success and error)