JASON: Hello, everyone, and welcome to another
episode of Learn with Jason. Welcome back Maxi Ferreira. So sorry I can't roll my Rs to say your name
properly. How are you? MAXI: Yeah, thank you for having me. Excited to work on some fun demos. JASON: The demo we did last time you were
here was one of my favorites we've worked on, and it's been extremely popular. But it actually recently broke, which is part
of the reason why you're back. But before we talk about that, let's talk
a little bit about you. For folks who aren't familiar with you and
your work, you want to give us a bit of a background on who you are, what you do? MAXI: Yeah, my name is Maxi. I work at Help Scout as a frontend engineer. I work at what other teams might be called
a frontend platform team. We work with our design system. We focus mostly on performance and frontend
architecture, that type of stuff. On the side, I like to work with sort of like
platform APIs. I like to test new APIs, new frameworks, and
one of the APIs that I've been playing with the most recently is the view transitions
API. So if you follow me on Twitter or you might
have seen some of my demos on Twitter, I just find it really, really fascinating and fun
to play with APIs. So I just love to spread the word about it. JASON: Excellent. Give me just one second. I'm getting an echo, and I'm not sure why. Can y'all -- let's see. Give me a quick check of your -- wait, it's
fixed? Or is it back? Maxi, can you give us a quick mic check? MAXI: Hello, hello. Still hearing the echo? JASON: Hold on one second. Let me try to get this fixed. I just moved my studio. If you've seen the show before, you might
recognize this is a new space. So I am attempting to fix this in a way that
doesn't cause bad load back. So Maxi, one more check? MAXI: Hello, can you hear me? JASON: How is that, y'all? Okay. That's better. All right. Sorry about that. And we are now in business. Okay. So, good. All right. So yeah, you've been working on a lot of this
stuff. So the demo that we did last time was for
an API that has been renamed. It was -- I think at the time it was called
the shared element transition API. Is that correct? MAXI: Exactly, yeah. That's one of the things I changed. It's now called view transitions. Other function names and things have also
changed. That's why the API broke on us. JASON: Got it, got it. And so let's go at a high level. What is the view transitions API? What problem does it solve? MAXI: So yeah, the main problem that it's
trying to solve is to allow you to do kind of animate and transitions between navigations,
right. So whether you're on a single-page application
or a multi-page application when you navigate to a completely different document, this API
allows you to do that transition in a sort of seamless way with a nice CSS controlled
animation. It can be used for other things. So I think the API has sort of two parts. One is the same document, view transitions
part, which is everything you can do with JavaScript on the same document. You can transition different elements on the
page. That doesn't necessarily need to involve a
page transition. So we can play with some simple demos now
with just changing an element on the page from one place to the next. Then there's the cross-document API, which
is the new part. This part didn't exist last year when we were
talking about this API. We didn't have this. So this is new. JASON: This is what we had to fake, right? We had to bring in, I think, turbo links,
so we could simulate a single-page app to get these transitions. So you're saying that's built into the browser
now? We don't need to bring in a JavaScript library
to do single-page app. We can do it with a multi-page app. MAXI: Yes, that's the part. That's still experimental for now, this multi-page
application support. But it's -- sort of the SPA version, which
was experimental last year when we were playing with this, we had to enable a feature flag. Now it's enabled in Chrome by default. So if you're using Chrome, you have this feature
enabled now. You don't have to enable anything. JASON: Got it. Got it. Well, that's super call. I'm really excited about just the whole possibility
of all this. It's such a cool -- let me just start this
over because I just tangled my thoughts in my head. I'm very excited by this because one of the
reasons that I think people have had a hard time with multi-page apps is when we introduce
single-page apps and introduced mobile applications, we suddenly got used to this idea that when
you navigate, you don't see a page refresh. You see, you know, sometimes just the content
refreshes in the main window, and you have the header navigation stuff. Then when you look at really nicely designed
apps, you actually see these beautiful transitions where an element will move from one section
of the page to the other. Without a way to do that in multi-page apps,
that's a significant downside of moving away from a single-page app architecture. And one of the kind of most valid reasons
I think people push back on this idea of, well, why don't you just use an MPA, you don't
need JavaScript, it's like, well, I need that app UX of moving between pages seamlessly. So why I find this so exciting is that it
actually gives us a valid path forward to get that experience of an app-like navigation,
an app-like experience of using the app without having to bring in more JavaScript. So there's, theoretically, a world here where
between the new CSS APIs, a lot of the new browser APIs, you could potentially build
an entire app that doesn't ship any JavaScript and feels like a mobile app. MAXI: Yeah, yeah, exactly. That's one of the main benefits, just shipping
less JavaScript, doing sort of less work on the main thread as well. A lot of this -- there are a lot of tools
for doing transitions on an SPA, but they're going to plug the main thread. So having this sort of built-in support, not
having to pull in a third party to do this type of thing, it's also really great. JASON: Yeah, that's extremely exciting. Okay. So right now, this is the -- the view transitions
API is partially stable. You said the SPA support is stable, but it's
still currently only in Chrome Canary? Or is the SPA part in all versions of Chrome-based
browsers? MAXI: It's on all versions of Chrome-based
browsers. So it should be if you're on Edge or Arc,
in Chrome-based browser should have this enabled. JASON: Oh, that's very exciting. And so the piece, the experimental piece is
the multi-page, like navigating between pages. For that, we need Chrome Canary, is that correct? MAXI: Yeah, exactly. We need Chrome Canary. JASON: Okay. And so this is one of those if you want to
experiment, you want to play, definitely try this out. But do be aware the multi-page stuff isn't
going to work in all browsers just yet. And similar to when we played with the shared
transition element API last year, it's subject to change. As the team learns more about how this works,
we might see that multi-page app setup shift a little bit. Okay. So part of me just wants to jump into this
and start coding, but I feel like -- is there anything else -- like as you've been building
with this, what are you finding feels the most magical about this API? MAXI: I find it super interesting that you
can do -- like, I was mentioning, you're not sort of restricted or limited to page transitions. You can do, you know, element transitions. You can do sort of like flip animations when
you want to reorder in some fashion. So if you want to do that with traditional
technologies, you need a bunch of JavaScript to calculate the position of the new elements
and then move them around. Doing that type of animation with this view
transitions API is very simple. We're going to see an example of how we can
do that. I'll say if you have too many elements on
the page, it's probably not the best thing because right now there are some sort of performance
problems that the team is working on. So you have to try not to have hundreds of
elements on the page moving at the same time. But for simple flip transitions where you
want to move some boxes around on the page, it's really great because you don't have to
worry about anything, really. The browser takes care of sort of morphing
the elements into the right places. Yeah, that to me is one of the things that
I don't use very often because I mostly use it for page transitions. I want to transition from one page to the
next. But this also is a really nice feature. Another thing -- as I'm talking, I'm remembering
another thing that's very cool is last time we talked about the -- so when you do a view
transition, the browser is basically taking two screenshots of the before and after states
of the page. Then it will transition between them. But the cool thing is that sort of the after
screenshot is not really a screenshot but sort of a live representation of the dom. So if you have a video playing or a GIF or
some animation, it will continue to play during that transition, which is very cool. It allows you if you have video playing, you
want to do a picture-in-picture type of animation, the video will continue to play. So it's not like you're in a frozen state
while you do the transition. JASON: That's super cool. I mean, I love -- that immediately got my
wheels turning on cool things we could do where if we can do something like that, then
you could theoretically have the Learn With Jason site -- right now the stream is being
live cast, but it's only on one page. But if we had this, what we could do is on
every page, you could have the player in the bottom right corner whenever we're live. Then when you go to the page where it's full
size, it would animate to full size. When you navigate away, animate back down. All of that would be possible with -- I mean,
we'll need a little JavaScript to get the player working and stuff. But eventually when we get the multi-page
in full support, that's -- like, it just works. That is magical. That stuff is so cool. I'm just -- you know, this is one of the spaces
that I think is maybe one of the most exciting in the web that's getting the least amount
of hype. This rapid advancement in the browser. The amount of stuff we can do with browser
APIs today is so incredible, especially compared to what I remember back in the day where you
spent all your time as a dev sort of wrestling with browser inconsistencies. Now we're seeing browser APIs steadily pull
things in that are universally supported. I mean, partially because just about everything
is Chromium. But even on Firefox, there's excellent parity. But you have these long-livid, stable, effectively
future-proof APIs. When something ships in the browser, it's
not going to break. The browser doesn't break backward compatibility. We don't talk enough about that because I've
spent way too much time going back and fixing something because the framework shifted and
changed its API. Now my stuff is broken if I try to update
to the latest version. But in the browser, that's just not a fear,
unless you're using something experimental. I just love it so much. So anyway. How about we jump in and actually play with
this a little bit? MAXI: Yeah, yeah. I'd love to. JASON: I can't wait. MAXI: And I thought we can actually start
with sort of like the very basics, to talk about the API, just a very minimalist, simple
demo to see how things work and implement it in an actual project. JASON: Perfect. Awesome. All right. So let me really quickly just give a shout
out. This episode, like every episode, is being
live captioned. We have White Coat Captioning. Rachel is here today. Thank you very much for being here. That's made possible by the support of our
sponsors. We've actually got new sponsors. I just haven't updated this part of the site
yet. We have Netlify staying on. Then we've got Nx, New Relic and Pluralsight
wrapping up the last quarter, the end of their sponsorship. So thank you to them for all they did. I do have a couple spots available if anybody
is interested in joining as a sponsor. We're talking to Maxi today. Make sure you go in and do a little follow
over there. Okay. So with that being said, I think you wanted
me to be using Chrome Canary today. I'm in Arc right now. Do you want to start here and move over later? MAXI: We can start with Arc right now. Any Chrome-based browser should work with
this. JASON: I think I used GitHub for -- yeah,
great. So then I can create a new pen. Do you want me to do anything with a template
or just go in? MAXI: No, just regular HTML. We're going to use HTML and CSS. JASON: Okay. MAXI: So let's start with a box. Let's do a little red box or blue box. And we're going to see how we can sort of
animate that with just a tiny bit of JavaScript. JASON: Oh, I can use this. And background. MAXI: Oh, nice. Perfect. JASON: All right. MAXI: Now let's declare sort of like a clicked
version or a clicked class for this box where we're maybe going to move it to the right
a little bit. JASON: Okay. Should I use relative position, or what do
you think? MAXI: We can do either. Yeah, just left, 300 pixels or so. I guess we have to do position absolute or
relative. JASON: That should work. So then if I add this -- MAXI: Yeah, perfect. That's perfect. JASON: Okay. MAXI: Now let's do some JavaScript to actually
apply that class when we click on the box. JASON: And we'll do a document.queryselector. Then we can box.addeventlistener. Okay. MAXI: Perfect. JASON: Look at it go. So then -- MAXI: Yeah, toggle. Perfect. So now we can actually do a transition. So what we can do is wrap that call to the
toggle of the class in a transition. So we can do document.startviewtransition. That takes a call back. In that call back, we will do the dom update,
which in this case is adding that class. And if we try it out now, we should see a
nice little fade-in, fade-out animation. JASON: Look at that. Okay. MAXI: So what's happening here is, as I was
mentioning before, when we make the call to start view transition, the browser sort of
takes a screenshot of the page, of the entire page, not just the box. Then it calls that callback that we are updating
the dom. At the end of the call back, it will take
another screenshot. Once you have the two screenshots, it will
sort of transition between them. The default transition is to do this fade
in, fade out. So the old screenshot will fade out, and the
new one will fade in at the same time. That's why we see that animation. We can control these with TSS, but what we
can do as well is we can tell the browser that a particular element, so in this case
our box, is the same element both on the old screenshot and the new screenshot. So the browser will say this element moved. So I'm going to move it to the place where
it's on the new screenshot. To do that, we have to apply a view transition
name to the box. So on the CSS, we can define a property called
view transition name. We can give any name, as long as it's unique. JASON: Oh, my god. That is so wonderfully simple. Like, it's just brilliant to me you can do
something like this in, what -- so including the wrapper, three lines of code. We took something that was originally very,
like -- it popped. It's an instant change, which is fine. We use apps like that all the time. But with three lines of code, we made it into
this nice, actual animated transition. And I can't really think of any other way
you could do that. I guess for this one, you could set the transition
to, you know, 200 milliseconds or whatever. But that's not going to hold up when you start
modifying the actual dom. MAXI: Exactly, yeah. For certain things, we can do like translate
-- animate the translate position and things like that. But this will take care of a bunch of things
for us. It automatically translates color. If it disappears from the screen and appears
again, we can control those sort of like enter and exit animations individually. And yeah, like you said, to me this is a perfect
example of a really good abstraction. It's very simple. We just called a function, applied a CSS property,
and we have a really powerful feature now in our hands. We can customize it with CSS and do other
stuff, but the API surface is very simple. We didn't have to do much. JASON: I saw a question in the chat just now
asking about is there any sort of keyframing available. So can you do anything complex with these,
or is it sort of pretty simple stuff? MAXI: Yeah, you can customize the transition
with keyframe animations. So you can find a custom keyframe animation
in CSS and apply that to the transition. JASON: Nice. And is this smart enough that if I, like,
rotate 180 degrees, will it -- look at it go! MAXI: You can change color. You can change the size as well. So we can play around with some things. And it will transition all of them. JASON: So cool. I also love that this is a top-level property
now, instead of having to be the transform with a million subproperties. Such a nice little upgrade. MAXI: Yeah, that's right. Okay. And one way we can also sort of control this
animation is with a selector of a pseudo element called view transition group. So we can define a new sort of CSS selection. View transition group. JASON: Is it double? MAXI: Yeah, that's right. It's double. Then in parentheses here, we have to pass
the name of what is the element that we're controlling. So in this case, it's the box. And here is where you can define your custom
animations. If you want to do something simple, we can
just say animation duration to like three seconds or something. We'll see how it will still use a default
animation, but it will be much slower. We can play with the timing function. So just a custom easing function and things
like that as well. JASON: Animation timing function. Is that right? MAXI: Yeah, I think so. You can do like easing out or one of those. So it kind of slows down at the end. JASON: Mm-hmm. A little more organic. MAXI: Yeah, I can actually give you this one. Let's see if that works. I'll paste one in the chat. That should be like a sort of bouncy animation. It goes to the right and comes back. JASON: And if we take this back down to the
default -- oh, that's way too fast. Maybe take it down to like one. Look at it go. That's pretty fun, right? MAXI: It's pretty cool. We can also sort of inspect the animation
in dev tools. So if you go to -- if you pop the animations
panel. You have to hit escape. Yeah, there you go. Oh, there's that kebab menu. JASON: Let me pull this to the side so we
can see it more easily. Then we have our animations tab here. MAXI: Yes. So now -- is that the animation? JASON: That's the wrong one. Where's our box? MAXI: So you can parse the panel and click
on the box. Now you can scroll. JASON: Ah, here it is. >> Louise: Scroll the little pink bar to the
right, and you can control the animation. JASON: Oh, cool. That's dope. MAXI: It's very useful, especially when you
have multiple elements on the page, like transitioning at the same time. It's really cool to see, you know, what's
going on, on the page. JASON: Well, yeah, just being able to -- all
right, I'm 250 milliseconds in. Where is everything on my screen? I do this all the time where I'm like trying
to get three things to look natural as they move together, and it doesn't. So I just have to bump by ten milliseconds
at a time until it starts to feel right. This, I had no idea this panel was here. I'm feeling foolish because I could have saved
myself a lot of heartache. MAXI: Yeah, it's super useful. I don't work with animations too much, but
if you are -- I know that designers love to sort of customize the animation down to the
millisecond, like you were saying. Everything has to be perfect. And this is a very cool tool to do that. You can also control the delay for your animation,
things like that. And on the left, we now see here all those
different -- on the bottom left, you see view transition. These are all the different pseudo elements
that the browser adds to the page when we do a transition. And we can sort of customize each one of them
with CSS. If we go to the elements tab -- oh, we are
on the elements tab. JASON: Yeah, I got to pull this down so we
can see. MAXI: So we can see them there at the top. JASON: Oh, cool. Okay. Yeah. MAXI: So those are added only during the duration
of the transition. When the transition finishes, they get removed. JASON: Got it. Okay. MAXI: Cool. So now that we have the basics, we can jump
to the more sort of real-world demo. I have a repo here I prepared. So let me -- JASON: For this one, I should open up Chrome
Canary, right? MAXI: We can stay in Arc for the first part. Well, we can jump directly to Canary if -- because
we're going to need it for the second part when we talk about this cross-document transition. JASON: Yeah, why don't I minimize this, and
I will pull up Canary, which I put here. And you sent me a repo. MAXI: I will spend you the repo. I will also share it on the Twitch chat, if
I can open it. JASON: I'll share it here. That's also puts it into my automatic link
saver. So here's my link. Everybody bear with me while I get signed
into all of my accounts. Am I even going to need this, actually? You know what, it happened so fast, it doesn't
matter. MAXI: Yeah, I don't think you're going to
need to sign in. We're just going to clone the repo and just
start to play with it locally. JASON: Okay. So let me open up one of these, and we will
do GitHub. Repo clone. MAXI: I see someone else in the chat discovered
the animation stuff. Chrome dev tools have so many hidden features. I was watching a talk a couple months ago. So many things. He shared like a hundred tips for the Chrome
dev tools. JASON: Incredible stuff. Like, it really is one of those -- it does
so many things that you can spend a whole career trying to become an expert in it. It's like any other sufficiently complex piece
of technology. The 80% is pretty fast to learn. That remaining 20% can take you the rest of
your life. MAXI: Exactly, yeah. JASON: Okay. So I've got the repo open here. Oh, wait. Let me actually open this folder. I just cloned it. I didn't actually open it. So I'm going to go into GitHub. There it is. All right. So here's our site. It is a -- I think I saw it's an Astro site. MAXI: It is. It's an Astro blog. Very simple. It's based on a template that is on the Astro
website. I think it's called tableau. I remove a lot of things from the template. We only have two pages now. We have a homepage and -- I think you're missing
a zero. JASON: Okay. MAXI: So you have like a homepage, and then
you can open one of the articles. That's it. Two pages. JASON: Okay. MAXI: And can you -- let's see. Can you resize the browser a tiny bit? There go. The first demo we want to see this grid layout. So if it's only -- yeah. What we're going to do here is sort of like
a filter. So the first part, we're going to play with
this JavaScript API for sort of same-page transitions. So we want to use what we saw before on the
CodePen to sort of filter this list of elements in a nicely animated fashion. JASON: Oh, right. Because we can click down. MAXI: Exactly. That's only partially implemented. So we have to finish implementing that sort
of list. So that is in a React component. This entire -- it's called tag selector. There you go. This entire website is just Astro components,
except for this component. So we're going to have to do some hiding. So yeah, the first thing we want to do is
finish implementing this use effect. So we have the list of articles on the page
there. We're just going to, you know, hide the ones
that don't have the selection. JASON: Got it. Okay. So the article category is the selection. MAXI: So the selection contains the selection
of -- we can actually console log this if you want to. So when you click on one of those tags, it
will be added to the selection. JASON: Okay. So then if I put this out, I'm going to put
this back at the bottom. We'll head to the console. We get our list of these. As we add things, we get a list. Okay. MAXI: Yeah, just basically a list. JASON: That makes sense. So the work we need to do is in our articles. We want to probably map over them, right? MAXI: Mm-hmm. And then the articles contain the category
or their tag in a data attribute. So you can access the category. JASON: If I look down here, I can see the
span. MAXI: Oh, that's in a different -- yeah, that's
in a different component. JASON: This is correct, though? MAXI: Yeah. I don't know if data or data set. I use data set, but I don't know if -- JASON: Oh, it is data set. You're right. So then we can say if the selection includes
-- MAXI: Yes. Yes, it's include. JASON: Then we can add article.classlist. Or no, remove. MAXI: Remove the hidden class. Exactly. JASON: So then, theoretically -- articles.map. Do I need to do something? MAXI: This is not completely an array. It's an array-like type of thing. So click on one of the tags, and this should
-- yeah. So I think what we should consider now is
the empty state. So when we have no tags, no selection. JASON: So then I need -- so we can just do,
like -- MAXI: We can add that to the if. JASON: I was just going to say if selection
length is less than one, we can just return. So we won't add anything. That way, we should get our category. Is that going to work? Or do you want me to do it a different way? MAXI: I think if you unselect technology -- if
you click on technology again, it will not filter. JASON: Oh, it breaks, doesn't it. MAXI: So I think the ifs can be like if not
selection.length. Or the other thing. JASON: Okay. So let me -- oh, boy. What's happening? MAXI: Then we have to remove the class hidden
as well. JASON: Oh, got it. Okay. I guess we could do it like those. MAXI: Exactly. And I think this should work now. JASON: Empty, filtered, empty. Great. So if we look at this in the grid view, we
can see that a little more obviously. Things are being filtered as expected. MAXI: Yep, nice. JASON: Okay, great. MAXI: So now what we can do is we can wrap
our logic inside of a transition. So we can do like document.startviewtransition. JASON: Is this right here? MAXI: Yeah. JASON: And this is going to be our wrapper. We'll move the whole thing in. Then would you do it like this? Or do you want to do it kind of around the
outside? MAXI: I think either way it works. Yeah, we can do it around the for each maybe. JASON: Yeah, let's do it around the outside. This would start it again for every dom element. I have no idea if that matters, but this at
least we're just doing it once. MAXI: Yeah, that would actually give us an
error probably because I think we can't start a transition while another transition is happening. JASON: Look how nice this looks. MAXI: Really, it's pretty nice, right? JASON: You just don't have to do anything,
and it already feels so good comparatively. MAXI: I know. It's so cool. You can just sprinkle these view transitions
around. It's magic. JASON: Yeah. I can already feel this is going to become
a central part of the way that I work. It just makes such a small difference but
such a good difference. And it really feels wonderful to work with
this. MAXI: It's also really good for backwards
compatibility. You have to check if it doesn't exist. Then you have to do the dom update manually. But other browsers would just not have the
animation, but it would continue to work. JASON: Yeah. Oh, dang. So cool. So, so cool. Okay. So actually, why don't we show how to do that
really quick. If we wanted to make this, like, we would
say filter articles. Then we would take each of these and put this
up in here. Then if we want to check, we can say if start
view transition in document, then we would document start view transition, and we would
filter articles. Or else we would just filter the articles. That way we have backward compatibility. It's still going to work even if the browser
doesn't support this yet. So it's a little bit more code, but now we
don't have to worry about backward compatibility. This will function in every browser as far
back as we can probably support these days, right? MAXI: Yeah, yeah. We're not doing anything special. Then the CSS, if we add any custom CSS, that
will just get ignored by the browser. So yeah, this will work everywhere. JASON: Incredible. Okay. So what's next? MAXI: Nice. So now what we can do is we can use the view
transition name tag, CSS tag. We can apply one for each one of these cards. Then instead of doing this fade in, fade out,
we can just move them around on the page as we filter. So to do that, we have to go to the card.Astro
component. I guess we can do it with JavaScript as well. But we're just going to apply probably to
that wrapper div. We're going to add a style tag. We're going to set this view transition name
to -- we need a prefix. So like image or card. JASON: And I need to make this into one of
these. Oh, come on. MAXI: There you go. So we need a prefix because the name needs
to start with a letter. It can't start with a number. And some of these logs start with numbers. JASON: And this is also just kind of a CSS
style. Like a prefix to help you logically group
things if you're going to debug them as well. MAXI: Right, exactly. Yeah. JASON: Okay. MAXI: So with this, let's see how it looks
with just adding this. It should start to move things around already. JASON: Oh, beautiful. Look at it go. MAXI: Yeah, everything goes to the right place. We didn't have to do any JavaScript. We only added that CSS property. JASON: Oh, it's so cool. It's beautiful. MAXI: It's very cool. Very cool. And we mentioned before, we only have I think
15 articles or so on the page. If we had hundreds of pages, hundreds of articles,
then we should probably do something like only add this view transition name, you know,
when you need it. So we would do this with JavaScript, for example. But in this case, it doesn't affect the performance. JASON: Yeah, then there's a question in the
chat about getting seamless transitions in Astro with the view transitions API. I think we're about to do that, right? MAXI: Yes, yes. We're going to do a -- JASON: So, sit tight. We're about to show you. MAXI: Yeah, we're going to have a page navigation
transition as well. But for now, I want to also take -- like,
now that we have this nice sort of transition on the same page that we have here, we can
play a little bit with adding some CSS rules to customize the enter and exit animations
that we apply. JASON: Okay. MAXI: So there's a styles CSS file that's
empty. Yeah, should be empty. And here we're going to start by defining
a couple keyframe animations. We're going to define one called scale out,
and that will be -- that will have a two property block that should set the scale to zero. Then we'll define another one that will fade
in that will set the opacity to one. We don't need to define the from here because
it will use whatever is the system opacity and scale. JASON: Okay. MAXI: And now we want to define an exit animation. Let's say when one of those cards disappear,
we scale it out. So what we can do is we can target -- we don't
need to define a new keyframe. We can use the scale-out keyframe. But we can target the pseudo element view
transition. Remember we had all those view transition
dash something. This is called view transition old. This is sort of the old one. And here we can set the animation to scale
out. JASON: Do I need to set any -- I can let everything
else be default, right? MAXI: Let's see how it works. Maybe everything uses default. Or maybe we can set the animation name. Oh, we're missing something. We need to path in parentheses which are the
elements. In this case, we target everything, which
uses an asterisk here. We're going to try this out now. JASON: It kind of worked. It got a little weird. MAXI: It got a little weird. But there's a little weirdness. We're missing one more thing. So we want to define the exit animation. And now to do that, we need to target this
old screenshot only when there is no new screenshot for this element. So we can do that after the asterisk, or after
the closing parentheses, we can do -- sorry, outside of the parentheses. JASON: Oh, oh. Got it. MAXI: We can do colon, only child. So the reason this works is there's an image
pair sort of view transition group. That contains the old screenshot and the new
screenshot. When the old screenshot is the only child,
we know this is an exit transition because there's no new screenshot. Let's do -- yeah, let's try that. See if that -- JASON: I'm trying to take shortcuts. There it is. MAXI: Yeah, I think you see that scale out. We can also do animation duration. JASON: Now you'll see it's much slower. MAXI: We can also customize the animation. Now we're targeting the new screenshot. That's also only child because we have a new
screenshot, but we don't have an old screenshot. Let's try fade in. Oh, the other elements are moving fast. So we should probably do -- let's do a view
transition group. Yeah, let's do a selection for view transition
group. And also set the animation duration to one
second here. We need the asterisk as well. JASON: Oh, right, right. MAXI: I'm not seeing the fade in. JASON: Yeah, it's popping in, not fading in. I think that means I messed something up. Do I need to set a default opacity or anything? MAXI: I don't think we need to. Oh, maybe we do. Let's set the from opacity to zero and try
that. Yeah, I think that's much better. JASON: There it is. MAXI: You can also, of course, do a scale
in. So if we want to also customize -- yeah, we
can apply both a fade in and scale in. JASON: Then for this, should I add a new -- MAXI: Yes, we can do that. We can also do the scale out and do the reverse. JASON: Can you double like that? MAXI: Would that work? JASON: Like put in two animation names. MAXI: I'm not sure if that works. We can try it. The way that I tested this was to do the entire
animation. Did it work? JASON: Okay. It did not. I don't know if that's because I got the syntax
wrong or what. But why don't we just drop this right down
here. MAXI: Oh, yeah. JASON: Then I can scale from zero as well. MAXI: Yeah. JASON: Beauty. MAXI: Looks very nice. JASON: And that's great. It feels immediately very appy. MAXI: Yeah, exactly. And we only did some CSS. We really only added one line of JavaScript
in this entire thing. JASON: And I can actually leave those out
now. MAXI: Yeah, that applies to everything. JASON: Great. This is awesome. Okay. MAXI: One limitation of this API that I know
the team is working on, so this is something that might be coming soon, is that the only
way we can sort of select which screenshots we want to control is either globally using
the asterisk or by name to refer to a specific element. We can't do sort of by group. Let's say I had other elements on the page,
but I only want to apply this to our cards, for example. That is not supported at the moment. So if we try to do card, dash, asterisk, to
match the cards, it won't work. So that is coming out. I'm pretty sure the team has received a lot
of feedback about this. So I think that's something coming up. JASON: Cool. MAXI: Okay. So now I think we can jump to the new stuff,
which is the MPA support for view transitions. For this, we actually need to enable a feature
flag in Chrome Canary. So you can go to Chrome flags. Search for view transition. And that one, yes. The one for documents. JASON: Okay. Relaunching. MAXI: Yep, perfect. JASON: All right. And there we go. MAXI: Yep. And the way we enable this is very simple. We just have to go to our layout.Astro file,
which contains our HTML layout. We have to add a meta tag here in the head
element. JASON: Okay. MAXI: So anywhere in the head, we can add
a meta tag. The name is view transition. View-transition. And the content is same origin. I'm not sure if there are other options available. I think same origin is the only one supported
right now. And with that, we already have -- so if you
navigate from this page to a blog post, we should already see things animate. And this is not an SPA. JASON: Watch, watch. Everybody watch. I'm clicking the forward and backwards buttons
and getting transitions, and it's updating -- like the URL is changing. So this is a multi-page app. MAXI: This is a multi-page app. There's no -- we can disable JavaScript if
you want to prove it. JASON: That is freaking cool. Okay. JavaScript is disabled. I'm going to reload for good measure. MAXI: Oh, we got the white because there was
a JavaScript plug-in. But yeah. JASON: Look at it. Yo, this is so freaking cool that just works. I don't even know how to -- ah, I love it. I love it when the browser just does these
things. Okay. Can we talk for just a second? If you were going to implement this in JavaScript
today, how much work would that be? Like, how much effort are you going to put
in to making this thing function? Like, you've got to pay attention to the browser
history. You've got to pay attention to where things
are on the page. You've got to add these effects to, you know,
do the flip. What is flip? It's first, last, invert, play? MAXI: I think so, yeah. JASON: I think that's what -- hold on. Let me verify that I'm right on that. MAXI: You have to remember what flip means. That's another thing. JASON: Yeah, you have to remember what it
means. Let's see. Flip animations. Has anybody defined it? You know, it's okay. MAXI: Oh, flip your animations. I think that's one of the OG articles. There you go. JASON: First, last, invert, play. Oh, my goodness, my memory is a steel trap. (Laughter) MAXI: Nice work. JASON: But yeah, you have to do all this calculation
where you know the start point, you know the end point. You have to work backwards to figure out how
to get it from the start point to the end point. Then you have to do that calculation, set
up an animation loop. You can get plug-ins and stuff to do this,
but then you have to catch the page navigation, and you have to simulate the page navigation
using something like a router. So you're either building all this yourself,
which is a huge pain, or you're grabbing different libraries to make these things work, which
is fine individually until you're trying to get the libraries to inter-op, in which case
you find yourself in a custom hook or use effect or whatever kind of tricky situation. All of that, like hundreds of lines of JavaScript,
just disappears with a meta tag. What absolute magic. Like, oh, my goodness. What a great time to be alive. MAXI: It is a great time. Yeah, some people call it -- I know that for
CSS, a lot of the features coming with CSS, they call it like a CSS golden era. There's really a lot of features coming to
the platform. Like the scroll-driven animations. Of course, view transitions. There are new elements coming. So it's a really great time to be a web dev. JASON: Yes. Okay. So we added the one meta tag and got the cross-page
transitions. What else? Like what else should we see here? MAXI: Well, we can do what we did last time. When you open one of those articles, the header
image exists in both the thumbnail and the article. So what we can do is similar to how we did
with our box, in our original CodePen, we can say these two elements are the same element,
actually. So I want you to morph them in place, move
it in place in stead of fading one in and fading the other out. And we do this by just applying the same view
transition name to both elements. JASON: Got it. MAXI: So one is in the card component. If you go to the card.Astro component, you
will find -- JASON: We are doing it with the -- MAXI: Yes, we have that transition name for
the entire card. So we can define a new one for just the image. JASON: Oh, I understand. So this is my image. I want the picture, right? MAXI: Yes, we want the picture, and we want
to apply a transition name to this image. So instead of card, it can be image. Yeah, exactly. Now we want to apply the same name to the
same -- yeah, the same tag to the card in our blog post, which is in -- what's the name
of the file? I think it's log. So there's the other picture. This is the full-size picture of the blog
post. JASON: All right. MAXI: So now by doing that -- JASON: Everything is still working. Oh. Oh. So good. Okay. So one thing that I just noticed is this one
seems to be beneath. Is there a way I can change the stack order
and put that one as higher Z index or something? MAXI: Yes, we can. So this is one of the things we'll probably
have to do dynamically. We can either remove the transition names
from the other elements, or we can apply it like a higher Z index to the one we're clicking
on. JASON: That's what I was thinking. We could do the higher Z index. And to do that, we just need to do that in
JavaScript? MAXI: I believe so because you need to know
which one is -- unless we can do it with CSS. I haven't tried it. I guess we can use maybe the active pseudo
selector. JASON: Yeah, so let's go with active. MAXI: Although, I'm not sure that will work. What we want to do is define the higher Z
index on the view transition screenshot, but that doesn't get an active state. That's just a screenshot. JASON: But it would be within, wouldn't it? So if we did active -- MAXI: It's not within because those are at
the top. JASON: Oh, you're right. Okay. MAXI: That is a good question, though. JASON: So we would need to do something like
just a little bit of when you click the link -- I think this is pretty straightforward
to solve. Let's do this. Let's do a script. Inside of it, we're going to do a document.queryselector
all. If it's a link like this, we will then say
-- no. Add event listener. So what we're going to do is -- oh, I have
to do a whole -- MAXI: Yeah, I think we need to do it for each
one. JASON: Fine. Okay. So then I'll add my link, event listener,
and then we will say E target query selector image. Then styles index equals -- wait, as is tradition. Okay. But I've done it wrong. Can I just do it like this? No. Okay. Fine. Still doesn't like it. It's not possibly null. How dare you. We'll just do one of these. Come on. How about that? How about you hush. Oh, come on. Well, you know what time it is. MAXI: Time for TS ignore. JASON: Get out of my code. (Laughter)
All right. Let's see if this works then. Oh, I did it wrong. MAXI: So because you're applying the Z index
to the image, but what's transitioning here is not actually that image, it's a screenshot
of the image. JASON: Oh, you're right. MAXI: But what we can do is we can set -- instead
of applying the view transition name to all the cards or to all the images, we can apply
to only the image that is going to transition. So we can do here the same selector you have
except instead of applying the Z index, we're applying the view transition name. Does that make sense? I think that should work. JASON: Yeah, so we're going to view transition. MAXI: We can set this to image active. And we need to match that in the -- oh, we
were in the slug. We should probably do this on the index page,
right? JASON: On the index page only? MAXI: I think so, yes. JASON: Okay. That I'm going to look in here real quick. Index, yep. Then we'll drop it down to the bottom. So that will update the clicked one to have
image active, which means that in slug, I need to change this to be image active. Is that right? MAXI: Yes. JASON: Okay. So instead of being one of these, it'll be
one of these. And theoretically, it will break entirely
because I did something wrong. Let's have this console log and make sure
I actually did a thing. Here's my index. I can also give up on this if you had something
else you wanted to show. I don't want to burn the rest of our time
trying to debug this. MAXI: No, I'm fine. We can also do -- let's see. I think this is important also to show. We can show very quickly sort of how to disable
or adjust some of these animations for users that might have the reduced motion setting
enabled on the browsers. Oh, is it style instead of styles? JASON: Cannot read properties of null. So it's actually not finding our -- oh, the
target is the image. Fascinating. So if I click here, though, it's the span. So then I would need to bubble up. Oh, this sucks. (Laughter)
Okay. So we'll have to find out how to get up to
the parent. So this is a fun loop. Is there a way to do -- MAXI: Well, if we do current target -- JASON: Current target. MAXI: That should be always the anchor tag. Yes. JASON: That is always the link. Okay. So that's what we want. I'm going to turn off the prevent default. I'm going to turn this off. Then that, theoretically, okay. MAXI: It is what we want. Now we still need to remove all of the other
-- we're still applying the transition to all the cards. JASON: Right. So back to the styles. MAXI: So if you go to the index and where
we're applying that style. JASON: Oh, it's in the cards, right? MAXI: Yes, in the cards. JASON: So we're going to take this out. MAXI: Let's remove the one on the card as
well, just to see if this works. Then we can figure out how to -- so there's
one at the top. JASON: Of course that doesn't work. I know how undo works. So I'm just going to do one of these. MAXI: Yeah, we broke this, but it should fix
the other one. JASON: And it does. This now looks like what we want, where it
pops in. Then if I come out here and grab one of these,
it goes to the right place. So this looks really good. Okay. MAXI: But we lost the other ability. So I guess -- why don't we do the inverse. Again apply the style to the card and the
images that we had before. We roll back. And apply to all the images as well. Then on the click event, instead of adding
one tag, we are going to -- yeah, let's also roll this one back, the one in the slug. To use the slug, yeah. So now here instead of adding one, what we
can do is let's remove all the view transitions. I don't know how much work it's going to be,
but let's remove all of the other view transition names from all the other elements except for
this one image. JASON: Oh, I got you. Okay. So then we would have the current target,
we would get the image. You want to do it on all the cards? MAXI: Everything that has a view transition
tag applied. JASON: Okay. So the way that the cards are set up is we've
got the style view transition name. So to target those -- MAXI: Let's target -- this has the class article. We can do all articles and set the view transition
name to undefined or something. JASON: Class articles. That's going to be document query selector
all. And then we can do articles for each. Article.style.view transition name equals
off. MAXI: Yep, and we need to do the same thing
for all the images as well. Yeah, for all images inside of the articles. Yeah, exactly. JASON: Article is possibly null. Style does not exist on type elements. That seems -- what am I -- oh, TypeScript. MAXI: Is this going to cause a build error? JASON: It really shouldn't. This is functional. What am I doing with this one? So I don't really need this image anymore. MAXI: Yeah, but we need to apply it. We're going to remove it also from the image
we're clicking. So we need to reapply to this image. JASON: Got it. Okay. So then we will image.style.view transition
name. And that one is image. MAXI: We can actually save the previous view
transition name. Save that in a constant or something. JASON: That's going to be image.style.view
transition name. I'm embarrassed to say that would have taken
me days to figure out. All right. So let's try this again. MAXI: See if that works. JASON: These work. They do what we want. Okay. Come back out here. MAXI: Nice. JASON: Beautiful. MAXI: Go back. Nice. JASON: Look at it go. This is gorgeous. This works so nicely. The forward and backward buttons don't cause
the application of those things, but I think I can live with that. This is great. This looks wonderful. I can see a lot of ways I would want to continue
tweaking this and trying new things and figuring out more that I can do with it. Do you know, off the top of your head, has
there been any talk of like -- when does this multi-page app transition API come out of
-- like go stable? MAXI: I'm not sure. I haven't heard any dates. I know they're working on it. I think they released the first version in,
I want to say, November of last year. And they've been working on it for, you know,
over six months. This is like behind a feature flag. So I want to say it's going to be pretty soon
because the SPA version didn't take that long to become stable. JASON: Sure. MAXI: So this might be hitting browsers soon. JASON: So as we're kind of running out of
time here, just to recap, the view transition API that we're using to do this, which is
the same page we are modifying something based on hidden visible classes, this is available
today in all Chromium browsers? Or is it also Firefox and Web Kit? MAXI: Only Chromium browsers for now. I know Safari and Firefox have been interested,
but I haven't heard anything about implementing it. JASON: Okay. So with this kind of browser detection fallback,
you can double check that the thing is available. Then add it progressively. So, nice progressive enhancement there. It'll work in all Chromium browsers today. So Arc, et cetera. If you want to use the multi-page view transitions,
it currently only works in Chrome Canary behind a feature flag. But if the precedent of how long it took them
to get the single-page app transitions holds, then we're probably six-ish months away from
seeing the multi-page app land. MAXI: Yeah, maybe. I hope so. I hope that's -- I don't want to speak for
the Chrome team. JASON: You know, there are very few things
I get to play with on the web where I just get that giddy feeling of, oh, my god, this
is so exciting. One of the places I continue to get that feeling
is with these new browser APIs. I'm so happy to see how far the browser has
come, how much power we have without having to install third-party libraries, without
having to maintain custom JavaScript. Like, this is some incredible stuff. So as we're kind of coming to the end, is
there anything you want to make sure people see, any resources, any demos that you want
to show off before we run out of time? MAXI: Yeah, so resources, there is a blog
post on Chrome. I'll share the link. It's the same blog post we shared before,
which has all the information you need to get started with this. So I will share the link. So there is examples of how to do pretty much
everything you can do with this API. There is also one thing we didn't talk about,
which is handling when you transition between elements that have different aspect ratios. So there are some tricks you can do with CSS
to make that a smooth transition. JASON: Nice. MAXI: Yeah. And then, yeah, if you check my Twitter account,
I share demos from time to time. Also follow Adam on Twitter. They work on this API all the time. Make sure to check them out. JASON: Let me hide a couple things here so
I can actually pull up these windows because I'm not logged in on Twitter, and apparently
you can't look at people's accounts without being logged in anymore. You mentioned Argyle. And who was the other account? MAXI: Bramus. They are the ones working on this API. So yeah, make sure -- they share demos as
well and share resources. JASON: Yeah, so much exciting stuff happening
in this space. And let me pull up your Twitter one more time
so that as I'm talking about you -- yeah, all right. So this is something that I think is immediately
useful. I'm going to start using this, like, today. I want to start using this right now. And for anybody who's interested, the SPA
version is available now in Chromium browsers with a nice progressive enhancement path. Is there anything else you want to say or
show off before I do the teardown? MAXI: No, check out the API. Give the team feedback as well. They always look for feedback. I was mentioning one of the limitations of
the API, and they're working on that. So it's going to just get better over the
next few months or years. So your feedback is very important. The team is looking for feedback. They want to build a robust feature. So if you play with it, make sure you give
them a shout. JASON: Awesome. All right. Well, with that, I think we're going to call
this one a success. We're going to find somebody to raid. And we will see you all next time. Maxi, thank you so much for taking time with
us today. MAXI: Yeah, thank you for having me. This was fun. JASON: Take care, y'all. MAXI: Bye, folks.