 Hi there, my friend and friends. In this video, we're going to see how we can create this pretty cool little filter thing with this nice little animation that sort of sorts things as we click on them. Honestly, thanks to the new view transitions API, this is insanely simple and easy to do. So we're going to look at how you can do it as much as possible in a way for you to be able to add this to your own lists instead of focusing on this specific list that we're looking at right here. We're also going to make sure that there's browser support for browsers that don't support the view transitions API yet and talk a little bit about some of the controls and stuff that we have with it. And so to do that, we're going to get started by jumping on over to here, and we're going to start making this happen. You can see we have some stuff in place, but it's very simple. And we're going to sort of build on it from here. So let's go take a look at my HTML because there's it's very simple what we need. We're right now, I just have a div that has a class of filter on it here. And then I have these buttons that are in here, and they do filter button. And the only thing that is kind of important is I do have this active class that is there. The other part here is I just have this UL that's my list of conferences. And then in there, each one of my conferences is an individual li the content in here could be whenever you need it to be. There's one other important thing, though, since we will be using JavaScript, I have set things up with data attributes. And so I do have a data filter on all of my buttons, we're using JavaScript, I could have grabbed the text from these, but I like to show what the JavaScript is sort of hooked into by using data attributes. So that's why I've set them all up with data attributes for each one of the buttons. So what filter are we using, I just gave each filter a name. And then here on each individual conference, you can see that let's just collapse those down. I've just given them the data category and put the category that they fall under. The only thing that you might want to do a little bit differently here, which might create a little bit of a difference with how you set up your filtering. When we click on different things is right now, like each one of these conferences can only really belong to one thing at a time, you might be doing this for portfolio. So maybe instead of a data category, you might do something like data react and data tailwind, let's say, just to have like this is a react and a tailwind project. So then you filter would find that and show that specific thing. But then by doing it this way, you could have projects that are part of more than one thing at a time. Instead of how I've set things up where everything only belongs to one category. But for how what I'm doing here, that just makes more sense. So we have five conferences here, a little sidebar at the bottom, but nothing too much. But we're going to see how we can make it all work and make it look good with our filtering. And the first thing we're going to do though is pay a little bit of attention to our button. And so the first thing we're going to do is sort of get these buttons working a little bit. And we can go into our JavaScript. And as you can see, we don't actually have anything in here yet. And we're going to need three different things as we go through here. So the first one we're going to need is the list or the filters themselves. So we're going to want to get our buttons. And we want the whole list of buttons and we want the individual one. And we do need both to do some things for. So we'll start off with our filter list. So I'm calling it a filter list. It's my buttons, or the div that contains my buttons, I should say, is going to be equal to my document dot query selector. And we're going to do my dot filter there. And then we do need each one of the individual buttons as well. So we're going to say my filter buttons is in this case, because we're grabbing this div, we can just say that our filter list and do our query selector in there instead. Because in this case, it just makes it a little bit faster. It's not going to make a big difference performance wise. But we've already isolated that. So we might as well only do our query selector all inside of there. And then we can do my filter dot filter button and get all of those. And just in case you're wondering what editor I'm using right now, because it does look a little bit different. And where I'm actually this project came from, you can see it right here. This is sort of what the inspiration for all of this was. And this is coming from a platform called I code this. I code this is a project by floor and pop and he has a team of people helping him with it where it's daily UI challenges. And they're really cool. And some of them are very small little just like individual cards or something that you can work on and other days are a lot bigger like we're working on today. And if you sign up for a free account, you get access to a new daily challenge every day for you to try out, you just click on it. If you want to do it, you hit start challenge, it brings you right into an editor that is in your browser, and you can get working on it. And there's a little toggle so you can see what you're trying to build. When you're done, you can submit your challenges. If I go back, you can actually see other people submissions as well. You can comment on them heart them. You can also see how they've done different things if you get stuck. So it's cool that you're not just sort of on your own with it. You can also see their code when if you go and take a look, you can see what they've done to be able to get there. I know it used to be that you had to submit your challenge before you could see it. So it is possible you might have to submit a challenge before you can actually access other people's code. But yeah, I think it's really cool and fun just for that. But if you sign up for a pro account, you get access to the full bat catalog where there's like 15 pages of these daily challenges, you also get access to bigger projects, like this one here where you get a Figma file, they have a number of these larger projects that you can get access to. They're also introducing learning paths and some other stuff. And if you look here, I'm actually on got early access to a new version of the code editor, where they have some settings and other stuff that you can set now, which is super handy, especially when you want larger font sizes, like I like to have. Now, if you'd like the sounds of that, and you want to sign up for a pro account, make sure that you use the coupon code Kevin at checkout. And by doing that, you'll get 10% off. And if you use the link that is just down below in the description, I just want to let you know that it is an affiliate link, which means that you'll get it at no extra cost to you. But it also does help support my channel a little bit at the same time. But with that out of the way, let's dive into here and get back into the fun part of writing some JavaScript. And people are always asking me for more JavaScript content. So I hope this is sort of the up that alley, even though we're not going to be doing too much as you're going to see the animation looks complex. It used to be hard ways to do this type of thing. It is all so easy now. It's incredible. So the last thing we're going to want here is our conferences themselves. So conferences, we'll do our document dot query selector. All and I'm going to just do dot conference individual. In this case, I'm not grabbing the list itself. I'm just grabbing all of the list items that I have. So that's going to be saved as my conferences. If you're doing this for portfolio pieces or whatever it is, just, you know, name it appropriately for what you want. I know some people like see me build the entire thing. If you do want to reference the code at any point, the link to the code is also in the description down below. Let's go on now and we'll get these buttons going. So the first thing we're going to do is you mentioned we have this active class here. So just so we can like visually see things happening. Let's come here and let's get that. So that's my filter dot BTN and we'll choose active and we'll keep it nice and simple. We'll do a background of black and color of white. And we're going to add a little box shadow on there too. Because if we look at the design that I'm basing this off of, there is definitely like a little box shadowy thing that's coming on that. And so let's do a 00, maybe a 0.5 rim and an RGB of we want black at maybe 0.2 or maybe a 0.3 would actually be better. But let's try 0.2. And actually that looks pretty good. So we have my active button there. The reason I wanted to do this CSS on screen though, instead of having it in place already, is because I want to add one more line here, which is going to be a pointer events of none, which just disables the button, meaning I can't actually click on it. So you'll see here, I get my little hand icon. I know not everyone likes that for buttons, but this is working. If I hover on that, we're not getting it because I can't click on the button, which just means when we're doing our filtering after, I'm not going to ask the browser to refilter something if it's already the one that selected. So basically, we've just made our this button here inert. So, you know, instead of using JavaScript to check if it's active and then don't do anything, we can just say that it's not clickable and then we're fine. Cool. So we have that in place. We have my active now. So what are we going to do? We're going to come down and start making a few different things happen. We're going to start off without the animations and then add them in two steps. The first step is just going to make it sort of crossfade, which is already pretty cool. And then one little extra thing, and all of a sudden the animations all come to life. It's really, really neat. I love this new thing, the view transitions API. So what do we need to do first is what we need to be able to click on those buttons. So let's do our filter buttons and say a for each. And we want to say for each individual button. And for each one of those, we want to do something. So we'll do an arrow function. We don't need the parentheses here, but I'm going to put it. So we have our arrow function there for every button. And that function is going to add an event listener and we want to listen for a click. So once again, we can do something when somebody actually clicks on one of our buttons. So really, we need to do two different things here. The first one is going to be to, you know, change the active button. And then the second thing that we're going to do is update or filter the list, filter the list. And the easy one here is the active button, though this isn't the second one here is pretty easy to so to be able to change the active button, we have to know what button was actually clicked on. So to do that, I'm going to come here where we're doing our arrow function. And I'm just going to put the letter E. And what this is going to do is capture the event itself. So when we click on something, you're going to get all of the information from the event and we can do stuff with that. So now if I come down here, what I can say is we're going to do just let's do it this way, we're going to say update active active button, we're just going to make a function for that. And we're going to pass this in, but not exactly, we're going to say E dot target, because the event is going to get captured. And then the target is the element itself that we clicked on. So it's going to capture the button that we've clicked on. So we're going to update the active button to be our target that we've clicked on. And then for the filter list here, we're going to do a, we'll say just filter events, and we'll turn that into a function, but we'll come back to this one after I'm going to comment it out for now, just because it's going to cause some issues, if not. So now this can't work yet, because we don't have a function called update active button. So let's go and add one in. So here we can say function, update active button. And we're going to say we want to make, you know, what's our new button going to be? We want to find the previously active button. And the reason we want to find the previously active button is to remove the active class from it. So I guess we can say and remove the active class from it. And then the second thing we need to do is add the active class to our new button. And this is actually slightly easier, though they're both pretty easy, but let's start there, because it is slightly easier. So we need to say new button, new button, and we can do class list. And then we need to say add, and we want to add our active nothing too complicated at all. So now if I click on a button, you can see, oh, we've added it on there. And as I go through, we've added it to all of them now. But of course we want to remove it from the other one first. So how can we find the previously active button? Well, we have our filter list. So we have this right here. So we're going to use that. So let's go to our filter list. And then I'm going to do a query selector in here. And I'm going to look for the button that already has the active on it. So we're going to look for a dot active. And then once we find that we're taking that and we're going to do class list. And we're going to remove active. The one thing that's really important here is this one has a dot. This one in this one do not have dots because this is a query selector. So we put in our selector here. Whereas this one is a class list remove. So then we because it knows it's a class, we don't put the dot. And here we're doing a class list ads. We do not put the dot I've done this too many times and it's spent forever trying to figure out why it was unworking. So make sure you don't make that mistake. Now, definitely we can get a variable for this and then remove it, but it's not very long. So I really don't mind having this just as one big string like that. And then we're left with this. So now when I go and I click on one, it just moves on over because first we're finding the one that has the active, we're removing it, then we're going to the new button and we're adding it on to the new one. Nice and easy. So perfect. That's working. We've already done change the active button. And because the name of this function is really straightforward and it says exactly what we're doing. I don't think we need this comment here. And here to the filter the list and then filter events, that's going to be our new function. So I'm not going to leave the comment there either. Comments are great. I encourage comments. But if the function names is exactly what you're doing, you don't really need a comment to also tell you what you're doing, in my opinion. So the second thing we want to do now is to filter our events. And this is where things get a little bit more interesting, I guess. So for that, we can come let's just come underneath this one, keep them in order, and we'll do a function of my filter events. Now, for this one to be able to work, there's going to be a few, we're going to have to pass something into here, they can get to here because we need to know like, what are we filtering? What's our filter, right? So if I click on front end, I want to only get my front end stuff. So right here at the top, we're going to come in, we're going to add a const is equal to and for this, we need you know, we want to we have our e here, which is great. So we're going to say, or we're going to say our filter, right? So const filter is going to be equal to our e target. And then we can do a get attribute this time attribute. And we're going to get the attribute of our data filter. And just to make sure this is working, let's do our console log, because that's always a nice way, a nice thing to do to ensure things do what you're expecting them to do. So when we click, we get our target get attribute. And so that should get our data filter. So front end, back end, or full stack. So if I open up my dev tools down here at the bottom, and I click on something, front end, back end, full stack, and all perfect. So I can close that down. It is working as intended. And I can remove that from here. And that just means filter events with that new filter that we've just grabbed. So I want to filter the events to only be front end or only be back end or be my full stack or whatever it is. Awesome. So down here, that filters, you know, we're going to pass that filter here. So here we're going to do our, we'll say event. I just realized here I'm saying events. And I think I've called things conferences too. And events might be a bit of an awkward thing because we have event listeners and you have event in JavaScript. So maybe filter conferences would be a little better. So maybe we should actually do that. We'll say filter comp instead. And then so this would be my function filter comp. And then event. So instead of event, we'll just do comp. So because conference is way too long to write, I'll make a typo every time. There we go. And I just want to make sure I think we're good. Because yeah, I've done event before and it just gets a little bit weird since we have events in JavaScript. And it I think simplifies things since we're dealing with conferences anyway. And of course for you, it could be filter portfolio or filter work or whatever it is, you know, make it make sense for what you're doing. So in this section, we're going to have to do a few different things. First, we're going to get each conference category category. Then we're going to we're going to check if that category matches the filter. Then if it matches, show that comp. And if not, hide that comp. Right, nice and simple, nothing too complicated. So how do we get each conference's category since that's the first thing that we need to do? Well, we're going to do a conferences and do a for each year. And just as a bit of a reminder, the conferences here is my document query selector all for everything that has the conference class on it. So it's each one of my allies that are in here, just each individual event or conference here is what we're grabbing. So for each one of those conferences, I'm just going to comp again, because if not, I'm going to make it typo. So for each one of those, we're going to do something. So we do an arrow function. And the first thing what we need to get each one and the exact same way we did that for our buttons over here, we got the attribute, we can do the same thing over here. So we can say const comp category is going to be equal to the comp get attribute, no, not animations, get attribute. And the attribute we want to get in this case, if we go and take a look is my data category. So you can do our data cat t gory right there. So we can grab our category. And now we want to check if that category matches with our filter, like we left in our comment right here. So this one will start off without worrying about the all and we'll add that back in because it's surprisingly easy to do to get that one to work properly. But we'll start here with just a nice simple if and we'd say if the filter is equal to our we called that our comp category. And I just realized I'm putting that down here, but we're going to have to wrap this all like that. Just because this if statement is going to be in the for each right here. So there we go. So if the filter is equal to our category, what do we want to do now? Well, in this case, we want to show the conference, but we already see the conference. So we'll sort of we'll add that back in in a second. But then we have our else statement. So else. And that means if the filter does not match our conference category, we'll do something else. And what we're going to do is comp dot we'll do a set attribute once again. And in this case, the set attribute that we're going to use is going to be hidden. So we're just going to hide it completely that takes it out of the flow of the document and everything it just vanishes away. But if you're setting an attribute, you need to say what attribute it is and what you're setting the value to it for or to I'm just going to put an empty string because for hidden, we don't need a true or anything like that. You could put true here and it would also work, but we can just leave it as an empty string. And that will work fine. So that means that our conferences that we're hiding are going to have the hidden on it makes sense. So that just means for the other ones, all I'm going to do here, if the filter does match, I'm just going to do a remove attribute. And when we remove an attribute, we don't pass it a value for the attribute. So we just have to say hidden, and it will work. So if we have it just like that, I'm probably driving people with OCD a little bit nuts, because in some places I'm using semicolons and in other places, I'm not. I do apologize. Good to pick one or the other. And everything should work, but it's not working. Just because here I put comf filter and here I wrote filter. So we're just going to make sure that those two match each other. And there we go. Look at that. It's already working. You could leave it like this if you wanted it to if you will not quite because our all isn't working. But if you don't care about the animation, you now have a filter list that's almost working for the all. I originally was going to do something a little bit more complex, but you don't really need to do anything. So all we have to do here is actually just say if the comp filter is equal to all, or if it's equal to comp category, some people don't like having two things here. So you could actually make this like an all and do an if else or if you just want a multiple if statements, whatever you prefer. For me, this is simple. If it's all, then the comp remove attribute, we're doing that for every one of them. So now, if I go here, I hit all, they all come in. Otherwise, we're hiding stuff away. So basically all saying remove attribute hidden from all. And if we have a filter, we're only removing it from the other ones. We're hiding the other ones, basically. So now, I think it's actually looking pretty good. It's working well. But we want to add in, I'm going to add a little bit of CSS just to improve the styling and try and match what we're aiming for right here a little bit more because I want to show you a cool thing we're going to do with the underlines because normally this would be easy, but we're going to have a little bit of a gotcha that we're going to run into along the way here. So let's come over to here and I'm just going to find my conferences, which shouldn't be too high up conference list. So we're going to say conference and let's start by doing it on all of them. So I'm going to say my padding bottom is let's just say two ram. I'm going to say my margin bottom is two ram. I'm going to say my border bottom is one pixel solid black. So that should give us some dividing lines that should come in except I did a boron instead of a bottom. And then we get those dividing lines that are coming in with the problem of having a dividing line on our last one. And I don't want that to be there. So normally what you could do in this case is something like a last and not sorry, not, and then say last child, last child, and then it's going to be fine because the last child doesn't get it. But we have a problem. As soon as I use my filters, that doesn't really help us out because anything, you know, my dev world, it's not the last child. So we're still getting the line here. And if I did it the other way around the first child, you'd get it the same way just backwards where you'd have the border on the top sometimes, but not always. And the spacing would actually be even potentially more off. So here I am going to use a little bit of modern CSS to actually pull this off in using the has selector just because it's cool. And it works. And it makes me happy that we can do stuff like this now, even though it looks a little bit weird. So I'm actually going to do another knot. And then in here, we're going to have our has selector. And we're going to do a plus. And we're going to do it the attribute of hidden. And the reason this works, so let's just show you that it works. There you go. We only have lines. It just works. Okay. So why is this working? And has just so you know, it has about 90% browser support at this stage. I think a shade below 90% browser support. So, you know, it's not perfect, but it's not bad. And what we're doing with this is it's saying that if it's not a last child, and it's also doesn't have so not has doesn't have a sibling that is also hidden. Right. So it's kind of an interesting way that we can set that up. So if it is the not the last child and the sibling coming after it is also not hidden. So right away, I think that's pretty awesome that we can do that. Now, sometimes with things like this, there's ways of using the other way around where you're starting with the first child and going the other way. The problem is then you'd be like if you're selecting the siblings coming after you're selecting the hidden ones. So we're really saying don't select it if the next sibling is hidden and don't select it if it is the last child. And I think that works really well. So I'm sticking with that. And yeah, there we go. So now we want to add in our animations. And just before we add in the animations, though, I do want to say that a veered away from the original design here was conferences in Bergen to do a tech conferences one. And I sort of did this on purpose. And the reason I did this on purpose was because I'm actually going to be speaking at that conference. And it's in Texas this January, as you can see there, January 30 until February 1. And I'm going to be speaking there alongside other people like James Q. Quick, Danny Thompson, Dave Gray, Kelly Vaughn and a bunch of other amazing speakers. And maybe even better than that is this event is really set up as a social event as well with a games night, a barbecue night, they do morning walks and runs. And it all takes place inside of a giant indoor water park. I'm really looking forward to finally meeting some of my audience. So if you can grab a ticket and make it, do please make sure to say hi while you're there. And if you are interested in it, the link is in the description if you want to learn more. But yeah, let's put that aside and get into doing our stuff on getting these animations to work. So what are we going to do for the animations? This is going to be depressingly simple, because it's stuff like this used to be pretty hard. And what are we going to do? We're just going to come up to where we are setting this up, this active button and our filter here, where we do this, we just want to tell the browser that it should animate from this to this. That's it. We just tell the browser to do it. So how do we do that? Well, all we have to say is document. And then we do a start view transition. And the start view transition is just going to be a function like we've been doing for a lot of stuff. Let me just space this out as touch. So we're going to say document start view transition. So start doing the transition because we're updating the DOM basically. So start view transition. And then here's how we're going to update the DOM. And by doing this, check this out. Magic, right? And not only is this like transitioning like that, if I make this a little bit smaller, so the sidebar is underneath, it even like fades that in and out. Like the whole thing is going, if you have a sidebar, let's move this a little smaller. So we have a sidebar now. Actually, let's do it like this. So now like as the sidebar disappears and comes in, if you look at the get started button, you can see even that like fades back into place and stuff. I think it's just so cool. So yeah, right away, you could leave it like this if you want to. It works. It's pretty cool. It's nice. The one problem is right now, if you're on Safari or Firefox, the whole thing is broken. That's not good, right? Well, we can create the fallback, which will just be the version without this really easily, but we do need to check for that just because right now this is JavaScript. So if the browser gets to this and it doesn't know what it is, it just notes out of there, right? It does not work. So we do need to build in a fallback for this. So to do the fallback, it's really nice and easy. You just come up here and we just need an if and we say document start view transitions or transition. And so we're saying if the document can't do a view transition, if it doesn't know what that is, we're going to do this. And that's literally all we have to do. We just put the same functions in our if statement where we don't have one and when we do have it. And that means if the browser does support view transitions, we get the little fading animation or very soon to be the better animation. And if it doesn't support it like Firefox right here, it just does this. That's it. It has a nice simple fallback to the non-animated version. And as I said, this is part of the view transitions API. It works really well. We're looking at the version of it right now for DOM manipulation, where we can do view transitions and then you do a DOM manipulation and we create animations there. This is also opening up the door to page transitions as well. But the view transitions like this for DOM manipulation is working in Chrome right now. The page transition version currently is only behind a flag in Chrome. Though if you start using Astro or some other stuff, they've opened up the doors to all of it through some polyfills and stuff. And it's really, really cool. We'll probably do a video on all of that one day as well. And I'm not even going to deep dive everything here because there is quite a bit to it. I just wanted to focus on this filter list. So we'll look at probably a deep dive into view transitions at one point as well because there's a lot with the different CSS stuff you can do for it. But let's get this animation working a little bit nicer now. And to be able to do that, we're going to break down a little bit of how view transitions work because by default, what we have is there's a view transitions. So we get this pseudo selector in CSS, view transition. And there's different parts to this. We have a group for a view transition and this is the before and after state. So you could do something like actually we could do this. Let's just to show you, I'm going to I'll explain this in a second, but let's do an animation duration. And we're going to say five seconds, ridiculously long. But if we wanted to, we could make that transition take five seconds. Super easy. And the group is actually something that we could break up into smaller pieces because this is including the beginning sort of the before and after state and how long, you know, it's grouping them together in a single group. But we also have access to our view transition transition old. And we have access to the copy that the new. So the way the view transitions for domination works basically is the browser takes a screenshot of before the animation. It takes a screenshot of what it's going to look like at the end and it just overlaps them and it lowers the opacity of one and brings in the opacity of the other one. And by default gives us the crossfade. You can come in with some of your own animations instead of having a crossfade. And the other thing that I just want to mention is there is a mixed blend mode on here. I forget what the default one is. We have black and white here. We probably wouldn't see a difference, but it is possible. If you're getting weird stuff happening that you want to avoid, you might need to put a mixed blend mode of none on there just to remove them. So just to throw that out there. But if you have like elements sliding in and out, you could use this new and old one to like, you know, fade one away as the other one slides in. There's lots of different things that are available for us. But we don't actually need to worry too much about this. The only thing that's important right now is right now, this is for my root, because it's doing it for the entire page, which is why we have, you know, the individual elements are fading in and out. But like when we had this at the smaller size and the sidebar had to move down or move up, like everything is happening, it's one to the other for the entire page. The other thing though is we can do different individual animations on different pieces. And this is something that I broke my head on, because I couldn't find much in the documentation, maybe I just missed it. But you can't have multiple things sharing one view transition name, because what I kept trying to do was go to my conference and do a view transition transition name and called it conference. And this is saying that this isn't a valid property, it is. This is how we name the different pieces that we want to animate individually. And so instead of selecting my root, I could do my view transition. Let's just do group for now. And here I would just write conference, and then do something here if I wanted to. So even we might look at this at one point, but the problem is if I do that, you'll notice that it broke everything. My animations are just all completely gone. Nothing is functioning. And that's because you cannot have multiple elements sharing a transition name. It was Chris Coyer's the only place I saw it mentioned in a tutorial-y blog thing that was just talking about how to do them. At that point, I'd figured it out and I was like, finally someone else who's mentioning this. Thank you, Chris. And I'll link to his article below too, because he did a cool thing with list items that would insert themselves in. Really neat. But yeah, the one thing we can't do is this. So one option you have is to do the conference and then do an nth. And we're not going to do this, but you could do nth child one and then give that a view transition name and then do two and give that a view transition name. So that's one option. Another option is to do it as an inline style. So here I could do style is equal to and then do view transition name and give it each one of them a unique name. And that sort of sucks as well. And I don't want to do that either. So what we're going to do is use JavaScript to do it since we're using JavaScript for all of this anyway. And to do that come all the way up. And I said we're going to need this again. So now we're finally going to use that. And the first thing we're going to do though, before we do that is let's come in and say let conference index be equal to zero. And then what we can do is our conferences for each conference. And for each one of those conferences, as usual, we want to do something. So we're going to do our function right there. And all we're doing, I'm just going to inline the style for each one of them. So we're going to say conference style. And then we're just going to say the view, not start view transition, just view transition name. If you're setting styles through JavaScript, just always know that what would be the kebab case in CSS. So the view transition name, which I deleted now would be normally kebab case in JavaScript, you just do it with camel case instead. And that's going to be equal to and we're just going to come here with back ticks so we can have some regular text and throw some JavaScript in there. And I'm going to do comp and then come here and then just do my conference index. And I was going to write this at the end, but it should go at the beginning, we're going to do a plus plus right there. So basically, it's going to go through each one of those. And it's going to use our conference index, but I use let here because I want it to update each time. So it's going to be a one, then a two, then a three, because it's going through each one of them. And so if we go and take a look, I don't know why I'm making that bigger, we want to go look in our dev tools. And if we inspect on the individual elements in here, we should see, that's the wrong thing. Here's my comp one, there we go. So we get the make that slightly bigger, the view transition name comp one comp two comp three comp four comp five. Nice thing now is you add another one, it automatically gets a name on it. And it's really important that each one of these has an individual view transition name if we want this to work. Because watch this, that's all we did anything else. And oh, it works, it slides everything. It's nice. If it looks a little janky for you, I promise you it's working really nice on here I am recording at 30 frames a second. So that could be a little part of it. It's just cool. Right. So it's because now what it's doing instead of taking a screenshot of the entire page and animating the entire thing just from one state to the other, it it's still doing that for the entire page. Because if we move this, the root is still getting the animation on it because you can see this still crossfades up and down as things are moving. But now it's also looking at each one of those li's and it's going, oh, that li needs to be down here. So I'm going to animate it down there. So it just works. And again, you could play with the timing of these if you wanted to, you could have different timing for each one if you wanted to whatever you want. But just for the simplicity of what we wanted here, I'm just blown away. And I'm super happy with that. And so yeah, I hope that wasn't disappointing in how simple that was. I said that it would be pretty easy. It took us a little while to get there, but I'm happy we got there. And with that, I just want to remind you not to forget to check out I code this with that link that is just down below. And with that, I would like to thank my supporters of awesome who are Web on Demand, Andrew, Tim, Simon, and Johnny, as well as all of my other patrons for their monthly support. And of course, until next time, don't forget to make your corner of the internet just a little bit more awesome.