Responsive Framer Motion with Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I'm going to show you how to customize your framer motion animations at different media break points using only Tailwind CSS and we're going to be working with this little modal demo which comes from tail and UI now I've already gone ahead and wired up framer motion so you can see we're using the static version of the dialog controlled with animate presence so we have our Mount and unmount animations defined here and here we see the overlay it goes from opacity 0 to opacity one and down here we see the panel which also fades in but also has a bit of scale to it and we can see that when we toggle it right here so pretty cool pretty easy to wire up frame or motion with Tailwind UI components I love using frame or motion for animation and this looks and works great but if we pop over to Tailwind UI we're going to see that they added a really nice detail to this simple alert component and you can see here it has you know a similar Behavior it's fading in and zooming in the middle but if I were to actually shrink this down to the mobile treatment we'll see that the panel moves to the bottom of the screen but the animation changes as well and when the dialog is shown it comes up from the bottom and then when it's closed it goes back down and there's no scaling going on here but when we're on a large screen we see a bit of scale and we don't have that vertical movement anymore so the treatment for the animation here is actually different based on the different media break points and if we look at the code and we come down to the transition component that they're using we can can see what's happening right here on small screens we are entering from a 16 pixel offset and we're entering two zero pixel offset that's that vertical movement but then once we get to the small break point we reset this to zero so that there's no vertical movement and instead we use scale and we set scale to 95 percent and then 100 and the opacity is there for both of those treatments so whenever I run into this it's always kind of a question about how best to do this in frame or motion because now we are in react JavaScript land which doesn't really have access to the media breakpoints in the same way that CSS does and so your first instinct here might be to reach for something like a use media query hook and I've used this before and maybe you say something like if we find out what SM corresponds to here we can see that SM is 640 pixels so now we have to come up here duplicate this something like Min width 640 pixels then we get an is small something like that and then you come down here and this is possible we could say something like if we're small then uh we'll keep a scale alone otherwise we'll set it to 90 percent and that's a way we could customize this but this is kind of a bummer we have to you know redefine the media query here we can't just use tailwind and there's also sometimes issues with this and server-side rendering so today I'm going to show you exactly how we can pull this off without using any hook or any new JavaScript code actually at all and that is if we go ahead and undo this it turns out that framework motion is able to animate not just between JavaScript Primitives here but also between CSS variables so if I were to set this to a variable let's say scale from and this is scale two and we were to set these CSS variables framer motion would be able to use them to trigger its animation and now here is the missing trick we can use Tailwind to set CSS properties and by doing so we can also use tailwind's responsive prefixes like sm all of these things to update those CSS variables values at different media breakpoints so that's exactly what we're going to do here let's first just refactor this to only ucss variables so we can see how it works and then we'll see how to set them with Tailwind so that we can apply responsive treatments so the easiest way to set CSS properties a right from our jsx here is with the style prop and we can say scale from is 0.8 and scale two is one and that typescript is going to give us an error here unless we type this as CSS properties so if we save this and we give it a shot it doesn't quite work and this is because we need to give framer motion a little bit more information about the units of these values here since now they're being represented in CSS so instead of 0.8 as a pure number let's go ahead and make this 80 percent and make this a hundred percent and now if we try it out we're going to see our scaling effect is back so that's kind of the first trick you need to remember when you're doing this Frame remotion can't infer the type of transform it needs to apply to the Dom into CSS from the JavaScript types because we're no longer working with JavaScript types right here these are being set as CSS variables in the Dom in the browser and then frame or motion is going to read from them but that's kind of what enables this whole trick to begin with so just remember to always put the unit here when using CSS variables so let's do the same thing for opacity and we'll call this opacity from and opacity to and we'll go ahead and set these as well opacity from goes from 0 to 100 and now everything is being controlled with our CSS properties so this is pretty cool we have our animation being driven from CSS properties but how can we customize these for different media breakpoints well if we were writing a CSS file we could do that but with the inline style tag there's no way to do that but fortunately this is exactly where Tailwind comes in with Tailwind we can actually define properties using arbitrary value syntax and then we can Define new properties using the responsive breakpoints so let's go ahead and refactor this to set the variables from tailwind and you might have seen a tailwind's arbitrary syntax before it looks kind of like this right here we're setting the background of our modal to white but let's say we wanted to change this and make this something like the hex code 333 right this square bracket syntax here is how you set arbitrary values in Tailwind for a given rule but we can use arbitrary properties and write any CSS we want in here at all so we could say background color is green and check that out it works and so this is how we can Define CSS properties like scale from to be 80 percent so uh let's get rid of that let's get our background of white back and there we see the scaling is back and let's just make it zero for fun and it should be scaling a lot more now so you can see we are in fact defining the CSS variable from Tailwind in fact if we were to come over here and find this element in the inspector here we see the inline style setting the variables but if we were to scroll down we're going to see our fun little arbitrary property rule which is just serving to set the CSS variable so very cool let's go ahead and add scale two we'll make that 100 and we'll make this eighty percent again and we'll also set opacity from to zero percent and we'll go ahead and graph that and set 2 to 100 and we should be able to get rid of this entire style prop save this and everything should work just like before okay here comes the fun part we have two customizations to make based on the screen size and if we go back to Tailwind UI we can see that at the small screen we want this to come up from the bottom and then move down a little bit and at the large screen size we want the scale but we don't want the scale at the small and we don't want the movement at the large so uh first let's go ahead and make this smaller so that we get that mobile treatment and here we can already see the scale kind of feels strange when it's at the bottom like that so how might we apply these rules only once we get to the small breakpoint well just like with any Tailwind utility we can prefix this with SM check this out no scaling going on at all but once I make this bigger we get our scale back how cool is that on screen size is smaller than 640 pixels this variable is not even defined there's no value and so this is going to be undefined and frame or motion is just going to ignore the scale property altogether now to be good citizens and kind of make this a little bit more predictable I usually like giving these a default uh just because of the way sometimes frame or motion composes these different properties together it's nice to have a value instead of undefined even though undefined Works in this case and this way kind of on small screens if I save that and we reload just to check this we're still basically animating from one to one for the scale which is fine it's not having an effect but once we get to the bigger screen here we can see that a hard little responsive arbitrary property takes effect so cool so easy no hooks it's robust to server side rendering uh the initial render will have knowledge of this sometimes in frame or motion you have initial Mount animations I have them disabled up here um because it doesn't really make sense for this case of the modal but uh having all of this in CSS available for the first paint is an awesome uh aspect of this solution we didn't have to install any libraries we didn't have to use JavaScript to measure anything absolutely love it so let's get the last little piece of it working here which is when we open this we want this to come up from the bottom and the way we can do that is with the Y property so let's add a new variable here y from and Y2 and we'll add a new arbitrary property here right at the beginning and we'll say y from let's say 16 pixels and we'll throw this one down here Y2 we'll bring it back to zero and now check that out little slide up it's a little subtle we can make it 32 if we wanted to a little more dramatic pretty nice and we got that nice little frame of motion bounce going on there and now when we make this bigger we get the center treatment and if I dismiss this you'll see it's actually still going down right if I were to make this even bigger you could see it we have both the scale and the Y but we want to kind of reset the Y back to zero zero so that it doesn't have any vertical movement on this large treatment so we could come here and do something like FM and then set the Y from to be zero pixels and uh that should actually take care of it which it does but an even cooler way to do this is to use the max width responsive prefixes so uh check this out if I were to add Max SN and we take a look at the rule that Tailwind is generating for us here this is using not to kind of invert the standard mobile first responsive prefixes and uh that is going to only set this rule if we're below 640 pixels so if we save this we should have exactly the same result but we don't and that is because I forgot to add the defaults here so let's add the fallback values for our y this is kind of what I was mentioning earlier and let's just make sure this works there we go we've got our scaling back and when we go to a small screen size it looks like we're getting a bit of scroll bar whenever we do this and I think that's because this is a little bit too big let's go back to 16 pixels and that looks like it takes care of it so uh these fallback values again they're important for the reasons we just saw makes this more predictable sometimes these things are composed together with the transform property and if there's no fallback value or doesn't have the right unit might not work and so that's just something to keep in mind but with this we are able to set the Y from and 2 on small screens and only on small screens then once we get to 640 we get to set the scale property and let's take a final look here we're on the small screen we see it coming up from the bottom and going down everything's fading in and when I make it bigger we've got no movement in the y direction and we've got our scaling back and again I think this is cool for so many reasons you don't have to redefine or look up the screen sizes from your Tailwind config to use them in JavaScript somehow you don't need to use a hook at all or wait for your page to render to measure something and see what the screen size is and because we're not using CSS transitions when we resize between these two we don't have any layout shift we don't have any recalculation or transitions going on because there's no transitions classes on our markup here so that's just another little benefit frame or motion only animates when the state actually changes but because everything's driven by CSS here from a layout perspective we can change the screen size and there's no flashing there's no animation at all so I absolutely love this solution this was a little tip I got from Adam Walden the creator of tailwind and Tailwind UI and it just shows you how powerful these arbitrary properties are you can do all sorts of cool things with them but this is the latest one I'm really jazzed about so I hope you like that and learned something if you want to learn more Tailwind you haven't done a lot with it yourself I have a course over on build UI that I released this summer and it teaches you how to learn Tailwind from scratch we do stuff with arbitrary properties and values we do all sorts of cool stuff so if you want to dive deeper into Tailwind check that out I'll leave a link in the description otherwise I'll leave a link to this demo in the description as well that's all I got for you today thank you very much and I'll see you next week foreign [Music]
Info
Channel: Sam Selikoff
Views: 52,175
Rating: undefined out of 5
Keywords:
Id: xSuxsfn13xg
Channel Id: undefined
Length: 15min 8sec (908 seconds)
Published: Thu Aug 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.