If you're reading this from pc, try to hover over some buttons in my navbar. Fancy, right? This is done with Framer Motion.
Framer motion is react animation library. In the rather old update they added layout animations. This is badly documented, as i couldn't find information about layout animations that i needed quickly.
So, how one does this?
What are layout animations
Firstly, we need to understand what layout animations are.
So, what is a layout animation, you may ask. This is rather simple. When you animate any of the following, this is considered layout animation:
- Position CSS (
flex
,grid
, etc) - Size css (
width
,height
,padding
and so on) - Position relative to another elements (i. e. list of posts reordering)
Adding a hover animation
Now that we understand what is layout animation, the only thing left to do implement this.
First of all, you should have a focused element state. In react you would do it like this before your return
:
You can use any state manager you want. I went with default react one, as it's simple and we don't need anything else for this example.
Now, say you have a <div>
with some <motion.div>
s from framer-motion. This may look like this:
Here we have a few things to note. I use onFocus on <Link>
to set focus. I recommend doing the same if you're using Next.js like me. On the <Button>
i have a relative class, so that <motion.div>
will take up the entire button.
We show <motion.div>
only when the element is focused. You don't need <AnimatePresence>
here, as this is a layout animation.
Keep the code clean
Of course, do not hardcode buttons into your navbar like this. I have my site config with navbar buttons and i just iterate through it.
Adding fading
The example above works, but it lacks fade-in and fade-out animations on hover. To implement them, let's change the code a little.
Change your motion.div part into something like this
Here we add AnimatePresence
. Without it, the exit animation won't work as the motion.div will just be deleted.
exit
, animate
and initial
are just simple fade-in and fade-out animations.
The final code should look like this:
Note about AnimatePresence
As you can see, we have <AnimatePresence>
for every <motion.div>
, as it gets applied only to the first child.
Bonus: Adding page transitions
Now you know how to do probably the most impressive part. Now all that's left is to add simple page transition animations.
I will add a simple fade-in and fade-out animations on page transition, as more complex animations require more code and deeper understanding of what framer-motion does.
Add a client component for it.
The component is simple, it's that you just need 'use client' to use pathname.
Then you just wrap your content in layout.tsx and you're basically done.
That's it for today.