CSS tried to come for my job — A practical guide to View Transitions for creative developers

Introduction to Cyd Stumpel's Creative CSS Work

The speaker introduces Cyd Stumpel, highlighting her unique approach to CSS as a tool for creativity and playfulness. Cyd's work exemplifies the versatility of CSS, showcasing its potential beyond traditional uses. The introduction sets the stage for Cyd's presentation, emphasizing her artistic use of CSS and her impact on the field.

Cyd Stumpel's Journey and Achievements

Cyd Stumpel shares her journey from a student attending CSS Day to becoming a speaker at the event. She discusses her work as a creative developer, highlighting award-winning projects like Broed and Kota. Cyd also mentions her role as a part-time teacher and her involvement with the Fish Doorbell project, which gained international attention. This segment provides insight into Cyd's career and her contributions to creative web development.

The Role of CSS in Creative Development

Cyd discusses the evolving role of CSS in her work, noting how it has simplified tasks that used to take much longer. She contrasts CSS with AI, emphasizing that CSS enhances creativity by handling tedious tasks, allowing developers to focus on innovative and engaging web experiences. This segment underscores the importance of CSS in modern web development and its potential to transform creative processes.

Introduction to View Transitions and FLIP Technique

Cyd introduces the concept of View Transitions and the FLIP animation technique, developed by Paul Lewis for performance optimization. She explains how FLIP works by recording start positions, applying end transforms, and inverting them for smoother animations. This segment lays the groundwork for understanding how Cyd utilizes these techniques in her projects, highlighting the performance benefits they offer.

JavaScript Transitions and Their Challenges

Cyd elaborates on the complexities of implementing page transitions using JavaScript, discussing libraries like Swup and the challenges of managing persistent items and third-party scripts. She acknowledges the control JavaScript offers but also points out its error-prone nature. This segment provides a detailed look at the intricacies of JavaScript transitions and sets the stage for exploring CSS alternatives.

Exploring CSS View Transitions

Cyd delves into CSS View Transitions, demonstrating their capabilities for creating smooth animations between pages. She explains the process of capturing snapshots and the default crossfade effect, showcasing examples of how these transitions can be enhanced with CSS. This segment highlights the simplicity and power of CSS View Transitions in creating engaging web experiences.

Advanced Techniques with CSS View Transitions

Cyd explores advanced techniques for CSS View Transitions, including the use of view-transition-class and view-transition-name for styling multiple elements. She demonstrates how to create complex animations with minimal CSS, emphasizing the efficiency and performance benefits of these methods. This segment showcases the potential of CSS for creating sophisticated animations without relying heavily on JavaScript.

Implementing Page Transitions with CSS

Cyd demonstrates how to implement page transitions using CSS, focusing on the use of view-transition-types and pagereveal events. She explains how to create specific styles for different transition types and enhance user experiences with staggered animations. This segment provides practical insights into using CSS for seamless page transitions, highlighting its flexibility and creative potential.

Creative Applications of CSS View Transitions

Cyd showcases creative applications of CSS View Transitions, including dynamic animations for text and images. She discusses the use of view-transition-classes for handling complex animations and the challenges of aspect ratio changes. This segment illustrates the artistic possibilities of CSS, encouraging developers to experiment with innovative designs and interactions.

Pros and Cons of CSS View Transitions

Cyd outlines the advantages and limitations of CSS View Transitions, praising their standardized functionality and reduced reliance on JavaScript. She highlights the challenges of aspect ratio changes and the current limitations of browser support. This segment provides a balanced view of CSS View Transitions, helping developers weigh their benefits and drawbacks in practical applications.

Q&A: Accessibility, JavaScript, and Creative Development

During the Q&A session, Cyd addresses questions about accessibility issues with view transitions, the necessity of JavaScript for page transitions, and the functionality on mobile devices. She also discusses her creative process and the balance between functionality and playfulness in web design. This segment offers valuable insights into the practical considerations and creative possibilities of using CSS in web development.

What I really love about what Cyd does is it's another aspect of CSS. So a lot of us use CSS for work.

I told you about Adam, how he kind of plays around and prototypes really quickly and adds that little bit of creativity and playfulness to CSS. But Cyd really takes that to an extreme.

CSS is kind of a toy. It's a way to play around and have fun and do creative things so you can use it more artistically.

So CSS is really versatile, and I think Cyd's work really shows that. And I'm sure you'll agree with me after seeing her. Please welcome Cyd Stumpel.

Thank you. Let's wake up the laptop. Does it work? Let's wake this one up. Yay. Okay, it works.

Let's refresh. Okay. Hello, I'm Cyd and I'm a creative developer and teacher from here, from Amsterdam. Last year I got very excited because I realized I could spell my name using the CSS Day balloons.

And this year I'm very excited because I get to speak in front of all of you. And CSS Day was actually the first conference that I ever went to back in 2018, and I was still a student then. And now a lot of my students are here in the audience and also a lot of my former teachers. And I bet you didn't think that I would ever be here, right? Let's be honest. I don't think so.

Cool. So a little bit about what I do. I try to use code to make the web more playful and engaging, and mostly I do that through animation. So I've won several awards for my work, like for this website, this is Broed, and they organize events for creative professionals in Utrecht and they will do that this year in November as well. So maybe something fun to explore. And this is for Kota. They're a company from England and they wanted to celebrate their 10 year anniversary. So they wanted to show off their work and also some of their employees. But by far my biggest flex is that I built the new Visdeurbel (Fish Doorbell) website. So who's familiar with Fish Doorbell? Fish Doorbell!

Yay. Okay, so. So if you're not familiar, in Utrecht, there is a lock in the water and a lot of fish need to go by because they migrate during the summer and they need to make new little fish. So we put a live stream underwater and people can push the fish doorbell if they see a fish. So then the lock keeper knows to open the lock. And it was - it has gotten a lot of international attention. Like for example, on Last Week Tonight with John Oliver.

Let's try it again.

There is a wholesome livestream of Dutch fish waiting at a gate and you could be watching it right now. Did you just hear me?

You could be watching patient Dutch fish. Why are you still here?

That's what I'm asking. So I'm a part time teacher, but I'm also a freelancer. So when I'm freelancing I mostly work alone, which, let's be honest, is great.

But I can really miss having someone to bounce ideas off of. So that's why I kind of jumped at a chance to start teaching at my alma mater, the University of Applied Sciences in Amsterdam. I teach there the two year associate degree, Frontend Design and Development and also at the Minor in Web Development. And my students kind of have no idea how lucky they are. Not because they're taught by me, that would be weird to say. But they are casually getting lectures from the likes of Jeremy Keith and Nils Binder and Julia Miocene and Cassie Evans and Roel Nieskens, and of course my favorite colleague, Sanne 't Hooft, who would love if you said hi to him. He's not shy at all. So truly my students are the reason that I'm standing here today because I was very comfortable animating everything with JavaScript using GSAP. I love GSAP.

But all the while I was pushing my students to try out new techniques.

So they were starting to ask me questions that I didn't really have the answers to, which gets awkward after a while.

So I decided I need to know more about this. And it kind of escalated in me rebuilding my entire portfolio with them. Was not necessarily the idea, but it is kind of in my character because for the last four years I've been rebuilding my portfolio. You might have seen some of these.

Not sure. Some people join a gym at New Year's, I make a new portfolio. So we're all here because we think that CSS is awesome and CSS Day is awesome, of course.

But we do need to talk about the elephant in the room because CSS did try to come for my job, because work that used to take me days can now be done in a much shorter time.

And to be honest, it's okay because CSS came for the boring and the hard parts of my job. And Comic Sans is okay if you use rainbow letters. I'm not sure if anyone has ever told you, but that's okay. So this is also not a clever segueway into how we should all embrace AI, because AI companies kind of promise to do the opposite. They want to take over the fun stuff, the creative thinking and stuff like that. So I think that CSS is doing it the right way because it's not here to take your job, just the hard part. And it allows you to spend more time to create fun, meaningful and weird stuff on the web.

And CSS can do the heavy lifting and we can do the magic.

Okay, so let's get into View Transitions. I'm going to talk about View Transitions, by the way. So to start we need to talk about FLIP. And FLIP is an animation technique. It was thought up by Paul Lewis to make more performance animations. And what kind of happens is you record the start position, you apply the end transforms, and then you quickly invert those transforms and then the animation is actually the removal of the inverted transforms, which is kind of weird.

But this is much more performant because we can do all the calculations in the first hundred milliseconds of when a browser is getting on a website, because that's the time that a user doesn't notice that anything is happening. So this was kind of unique and I've used it a lot.

So I've created a lot of page transitions using JavaScript, and I probably will in the future as well, to be honest. I usually use a library called Swup to create all the weird routing stuff that you have to do because you're messing with the native routing of a browser. But Swup is great for that. They also allow native view transitions in there. But how do JavaScript transitions usually work? Well, you usually only animate the stuff that's within the main tag, so you don't animate the header or the footer. And that means that if you need a persistent item between two pages, for example, an image, you would put that image outside of the main tag so it will just remain there. You position it on top of the item that it was actually on, and then you animate it to the correct place on the new page and finally you remove that item.

So that's how I would do it in JavaScript. There are some pros and cons to this, of course, so it's great for control freaks because you have full creative control. You can do whatever you want. You can take as long as you want, and it is still HTML, which means that you can manipulate it during the transition.

It's also able to handle WebGL animations, which I've done a few of. I don't think it's possible with view transitions. I would love to see it if it is so hit me up. But some cons are that the setup is quite complicated. Something to get used to. There's lots of calculations and code going on, so it's very error prone.

Things like PopState and resize can cause really weird issues because imagine you've put an item outside of the main content and during the transition someone goes one page back, the item will just be there floating around like stuff like that. I usually just trigger, refresh. Sorry, refresh. And then there's the weird stuff because things like full page navigations, you have to manually close them because usually the navigation is outside of the main tag and then you have to close that. It's kind of a bug and a feature though, because you can now animate the navigation closing, which is kind of nice.

You have to kill processes like GSAP, ScrollTrigger and WebGL Renderer, stuff like that, because otherwise they will just keep running.

And I'm using a lot of WordPress. And then you have to make sure that third party scripts like For Gravity Forms or something are loaded on every page because otherwise your forms won't submit stuff like that. Kind of weird, but JavaScript triggered transitions may not be great, but if you're about to bash them in the next break, please remember that my ears are very good. And also that CSS View Transitions wouldn't be where they are without years of JavaScript pioneers pushing the boundaries of the Web. We're standing on the shoulders of giants like the contributors on Codrops, but also maintainers of libraries like GSAP and Framer Motion. But even websites like Awwwards and FWA, which some people may look down on. And I get it because you basically buy an award, but they have encouraged people to create new things and also to create a lot of the same things too.

I don't have Internet. I'm very much prepared for everything.

Let's go.

It's nice to look at someone fail to enable hotspots.

Come on.

Yes, Internet. And such a nice page too. You wouldn't want to miss this. So can we create the kind of transitions that I used to do with JavaScript in CSS?

Well, kind of. So in its most simple form, field transitions do something like this. Will they do something like this? Let's refresh again.

Yeah. Okay. So they create a nice little crossfade.

You probably can't really tell. I'll show you slower later. You could also do something like this. Make it feel a little bit like an app, but in its most complicated form we can do stuff like this.

This is a website I'm working on for a Dutch photographer.

His name is Michiel Rotgans. It was designed by Tim Borst, who gave me my first job. And I'm using view transitions here to basically animate between two states.

So you can use it for page transitions, for filtering, for sorting, for loading more animations, and you can just use it in production if you don't care about Firefox especially.

So, field transitions used to only be available on SPAs or single page apps, and those are apps that handle routing through JavaScript instead of just using links. They are also known as same- document view transitions and they have now also been available for about a year on MPAs or multiple page apps. But you might be more familiar with RFWs or regular fucking websites. And these are also known as cross documents view transitions. So all you need to do to make the simplest form of view transitions work between your pages is just add @viewtransition {navigation: auto; And if you want to Trigger it from JavaScript, you can use document.

StartViewTransition and then do the thing you want to move or change or filter out inside the function.

And what basically happens when you use view transitions, the most simple form between pages, you create a snapshot of the first page, you create a snapshot of the second page, and then you check if there are any changes in position, size or rotation. And then it will crossfade. This is not actually a crossfade, but imagine a crossfade between two states because by default the snapshots are the same size, so there's no change in position, rotation or size.

So let's go into this simple example.

Is this big enough? Probably not.

This must be big enough. So, if you've never seen the animations panel, you can find it in 'more tools' and then animations.

With the animations panel you can slow down your animations, which is very handy when you're doing view transitions. So let's finally see that crossfade I was talking about. Yeah, nice. And we can also switch to this moving animation and we can even pause it, which is really cool because now we can inspect what happens in the HTML because there's actually a pseudo element added to the HTML as long as the view transition is going on. And inside of the view transition there will be a view transition group for each named element. And by default that's only the root, so only the HTML is captured by default. But you could add to this and there will be a new view transition group for the new named elements. So on the group all the... let's close this.. let's open this. All the transforms are happening. So the sizing, the positioning and the rotating and inside of that is a view transition image pair. And that's basically there for the isolation isolate line. Because by default the old and the new states have a mixed blend mode going on, and you don't want to mix that with anything else. So you can use isolation isolate to do that and you can hover over these and you can actually see the two different states.

You can also see that you can no longer click on this, so it's no longer interactive. Okay, let's go back.

So by default there's only a snapshot of the root elements, but we can add things to it. Like for example, this imaginary image.

Let's say I put a view transition name on it. Then the browser knows that I want to animate that and that actually does change in size and maybe a little bit in position.

Yeah. Okay. So we can do that with view transition name and then the name of the thing that we want to add. But these names need to be unique, so you can't have more than one view transition name of image on the same page. Between pages.

you do want that, because then you tell the browser that these are the same elements. So what happens when you have multiple images?

Well, if you're using a CMS anyway, it's quite easy. You can just use the ID, but you can also just use a number if you're just writing HTML. I'm using a vt - CSS variable to set the view transition names just because otherwise your HTML gets very long and starts to look very tail windy and we don't want to go there. So, another thing that I'm doing right here is repeating the same styling for each separate image. And we're very lucky that we don't have to do that anymore because we can use 'view-transition-class' to style multiple elements the same way. And how you use that is with the dot in front of it.

So they still have to have unique view transition names, but you can use a class to style multiple items.

There's also - this is very exciting for same document view transitions - you can use 'match-element' and then the naming will be automatic.

So that would save a lot of trouble. I think this was supported at Safari at some point and now it's not. So they were, they were calling it auto, but I haven't really looked into it. So it's probably a surefire way to make your view transitions break on Safari.

And Chrome is also, I think, leading the way in both nested view transitions and scoped view transitions, which could solve problems with that - view transitions are all in the top layer, and also that you maybe want to trigger only specific view transitions. So that's kind of cool. But I'm not talking about that. Something that is very useful if you want to use this in production, like me, are view transition 'types'.

And you can call that directly from 'document.startViewTransition'.

But you can also use the new 'pagereveal' event, which is triggered right before view transitions are initiated. And then you can get the old URL and the new UR and based on that logic - there's a lot of weird coding going on. you can add a type to the current view transition using the event. Still with me. Okay, cool. So in CSS you can use it like this.

So we can say 'active-view-transition-type' and then the name that we decided, so this name can be anything you want, which is also kind of cool because then you can make your code more understandable to you.

So another cool thing, there are so much cool things. The old and new states of view transitions are also quite interesting because all the animation is going to happen on the group or the transitioning... transforming is going to happen on the group. But whether a group has an old and a new state kind of depends on if the element was there before, if it was added, or if it was removed. So, for example, when you're sorting, then all the items will have an old and a new state because you're just changing the position of elements. So I've represented the old state with a red rectangle and the new state with a green rectangle.

So for sorting they will have both. But if you're for example, filtering out items, then they will only have an old state, so they will only have this red rectangle going on. You can see that right here and right here.. it's going too fast... and then if you're adding back items using filter, then you will only have a new state. And you're like: 'why do I need to know this?' Well, you can do fun stuff with this. So these are all famous women in tech and I forgot to disable everything... don't look.. spoilers!

Okay, cool. So this is probably too small.

Does this help? Cool.

Okay, so we're first checking if 'Document.startViewTransition' is supported and if it's not, we're just going to go straight to the filtering anyway. I'm doing the same thing for the sorting and if it is supported, we're going to start a view transition using 'document.startViewTransition' and inside there's a function where I'm doing the same filter, so I'm just only setting item to 'display none'.

It's not a very sophisticated filter and everyone will probably see something like this.

So just items removing, items adding.

But we can easily enhance this by giving each of these images a unique view transition name. So I've added that as a CSS variable to each one. So there's a style - 'view transition', and the first four letters of the name. And if we add that to CSS and we try to sort now...

now.. instant!

That's all it takes. So that's kind of cool.

Then if we want to filter out items, you can see that they're fading out, which is not a very nice animation, and also they're fading back in.

But we can check with CSS if something is an only child.

So if there's only an old state because we're filtering things out, then we can check if the 'view-transition-old' is an only child and use 'animation-name: scale-out;' which just scales to zero. So now when items are removed, they are scaling out. That's just a few more lines of CSS, which is very powerful.

Then for the new items, we can check if 'view-transition-new' is an only child because then items are added back to the DOM so we can filter out and we scale out, and now they scale back in. So I've added a slight delay as well to give the items some time to get to the correct place. So it looks a little bit nicer.

But, yeah, this is just a few lines of CSS.

I don't even know if I would be able to make this performant with JavaScript.

And the sorting is still working as before, because then you still have an old and a new state. Cool. Are you ready for the fun stuff? I hope so, yes. Maybe I should actually open this in Canary because then I have a nice little stagger going on. That's just why we're viewing this in Canary, because of the sibling index and stagger. Okay. So there's a lot happening because it's one of my websites, so I created the conference website, by the way... I think that's my thing now. I did that for Beyond Tellerrand as well - thank you. So what we can do, or what is happening when I'm hovering over a speaker, you can see that both the name and the talk title is changing.

And then when I click an item, then the name is still here.

And also this is still here. So we could do something with that. There's lots of possibility for animation. So usually when I would get a design like this and it's flat, I really like when designers are like: 'oh, you decide...

like, you can decide the animation.' That's my favorite thing. And I designed this so I can decide. Let's start with the title animation.

I need to check there. Yes. Cool.

Okay, so I have this...

wow... Hover animation going on.

So I'm getting all the speaker cards... Jesus - all the speaker cards. And when I'm mouse entering, I'm changing the name and the talk title and I'm just doing that like normal now. But if I want to make this into a view transition, it's quite easy. First thing I need to do is check if view transitions are supported.

So 'if (document.startViewTransition)', and if it's not, I'm just going to do this, just the title and the talk title. But if it is supported, I'm going to do 'document.startViewTransition' and that's a function, and normally I would make another function in here, but I also want to use the types. So what I can do is make this into an object instead. So...go away.. - yes, thank you. What I'm going to do is use the 'update' function here and I'm going to put this in there or copy it in there.

And then I'm going to add types and you could add multiple types, which can be useful. I have used it before.

Sometimes it's nice when you have a boolean as well, a boolean value as well kind of thing. And I'm going to name it 'title-animation'.

Okay, so now nothing much is going to change because there's only like a slight crossfade going on, but not much else.

And I'm going to go to CSS and let's see, I'm going to have to name all the things, like I need to name this title and also the talk title thing.

So.. I'm very original. So those are named 'title' and 'talk-title'.

And I've added a view transition class to both as well. So we can do the same animation on both these elements. Because what I want to do is when a new title is coming in, I want to animate it in from the bottom and I want to animate the old title out to the top so I can use view transition new and old again.

So first I have set.

Oh, no, that's not it. It's much larger today.

You can't even see the whole line. Does anyone know how to. No, never mind, it's fine. Maybe one smaller. Are you still?

Okay, cool. Okay. So I've put 'mask-image' around both of these items that's basically like clip path, but you can add nice fuzzy edges with a linear gradient so it looks just a little bit nicer. So I've put that on the group. But the old and the new items I want to animate. So I'm animating. At first, I'm setting some defaults. I'm setting the default duration to 0.3 seconds.

And then I'm animating the new text from the bottom in. And the bottom in animation goes from 'translateY(100%)' to 'translateY(0)', and I'm animating the old one out through the top, so it goes from zero to minus 100%.

So now. Beautiful. Cool.

Yeah, that's nice. Right? Okay.

But we still want to do more. We want to create transitions between pages.

So now when I click Adam, nothing happens, and Adam deserves more than that. So let's do something about that. Let's go there.

So first thing I need to do is add...

Oh, I need to do one more thing. Okay, we'll get to the page transitions later. There's one more issue here, because now when I'm hovering quickly, you don't see the hover animation anymore - you notice? That's because the pseudo elements of view-transition is on top of everything. So we don't want that. So I'm adding 'pointer-events: none:' to that. But I'm only doing that. Now we're getting to the types part. You probably think, why did you use types? This is why. Because when I'm hovering over items, I want to disable the pointer events on the view transition, and I also want to disable the root 'view-transition- name' so it won't capture the root anymore. So you can see the hover animation going on. Cool. Okay. So now when I go really quickly, it kind of breaks, but that's fine, at least we have a hover animation. Okay, cool. So now we're going to animate between pages, and if you've been paying attention, you know that you need this '@view-transition {navigation: auto:' And now some things are animating. That's because I put view transition names on things. It's not just automatically - it would just create a crossfade between pages, but I've added a view transition name that's unique to Adam's picture and also on the page where it ends up. So, okay. Kind of cool.

But it can be better, of course. So I've also created 'view-transition-types' for '(overview-to-speaker)' and '(speaker-to-overview)'. So now we come into this very complicated bit of code or complicated looking - it is not that complicated. So I need a 'pagereveal' event to get the 'from?' and the 'to.' URL, and based on those URLs I'm either returning '(overview-to-speaker)' or '(speaker-to-overview)'.

So I'm either - or 'normal' but you don't really get that. That's the only two possibilities actually.

So now I can use those to create specific styles. So I want to make sure that the view transition duration for the speaker card group I need to add one more thing. I need to make sure that the view transition class of speaker card is on both this item and this item. So now I've done that. So now I can style them together. I've set the animation duration to 0.6 seconds. I'm removing the animation from the old and the new speaker or the old and the new view transition because I don't need that because the image is the same size in both states. So I'm just removing that animation. Save the browser a little thing. Then when I click an item, when I click Adam, I'm sorry Adam, I'm going to mention your name a lot. Then Adam will have an old and a new state, but all the other speakers will only have an old state because they are not there in the new state. So I can use the only child thing again to make sure that they all have a scale out animation and they also have a slightly shorter animation time.

I'm also going to do that for the new ones so they animate in. So I'm doing a scale in animation and I'm using a slight delay to give items time to get to the correct place again.

So let's do that nicer.

But it can be even nicer because I've done something that's a little bit gross.

I've added an index to each group.

I mean it works. So this Steven has 0, 1, 2, 3, 4, 5, etc.

And I can use that index to create a nice stagger animation.

I would like to use sibling index for this somehow, but I don't think that's possible. But in my mind it should be possible somehow. So I'm adding an animation delay where I'm multiplying the index with a very short amount so 0.03 seconds. So the first item will be 0 seconds delayed and this will be 0.03 seconds, 0.06 seconds, et cetera. And I'm doing the same for the new ones only I need to add that delay that I added right here.

So I'm removing this one and now this is going to be nice. Yes.

Okay, cool. Thank you.

Let's see. I also have some styles that are specific from '(overview-to-speaker)'.

So I'm... the animation delay is a little bit longer when we're going from overview to speaker than speaker to overview. Just have to trust me. And I'm using an '--ease' by default, but I'm changing the '--ease-in' to an '--ease-out' animation. And to be honest, I don't really know about eases.

I just do what feels good. I'm not sure if anyone knows the science behind it, probably Miriam, but I'm changing it to an '--ease-out' animation because that's just a little bit nicer.

So now it looks a little bit better because it kind of waits to animate until the other items are faded out.

Okay, now you've probably seen this monstrosity and thought, what the hell is that? Right? Or haven't you paid attention? It doesn't really look good. Okay, let's fix that and let's do that. I'm not sure how I am on time though. I'm not sure if that timer is correct, but I think it's fine. Okay, so I've added.. no, I haven't added.. I am adding View Transition Classes to all these things. So like the properties, all these things have a view transition name that's unique, but they also have a view transition class that's equal to '.code-prop-value'.

And then all these ones are '.code-prop-character' and these ones too, because they will move throughout the animation and I want to make sure that I can catch them.

And then this makes sense in my head. I'm not sure if it's okay for you. So let's do the '.code-prop-value'. I'm adding an animation delay and I'm setting the animation duration to 0 seconds because I don't want it to animate, but I do want there to be a delay. So I did this. And then for the '.code-character', so like the semicolons and the colons, I'm using a very short animation duration, so they will move but very quickly.

Then of course, we have to mention Jake Archibald because he really figured out the hard stuff on handling Aspect Ratios, because that's kind of weird because they are snapshots, they are kind of images.

Not allowed to say that, I think, but they are kind of images.

So we need to do some hacking. And this is what he says that I should do. So I trust him. And I did that.

And then we're.. oh, this is...

once we're animating the old value, let's do this in the correct order. That makes more sense.

Yes. We're animating the old value from right to left and the new value from left to right as if we're typing. It doesn't really look like that, but it's fine.

So now Foley.

Yeah, that's the right sound. Thank you. It's exactly correct. Cool.

I've done some more weird stuff because I thought maybe I should experiment a little bit. But I found another great demo by Jake Archibald.

He had this demo where he interrupted a view transition using JavaScript and he did that based on drag. So I thought maybe it's cool to do that for a dialogue kind of thing. We can drag and then play it frame by frame or something.

Kind of cool. But it is a little bit broken because if you're going like this and then you want to open it again, it just closes.

So maybe I need a little bit more help from Jake.

But it is kind of cool because we're doing a lot of stuff. I need to be honest, I did a lot of this with ChatGPT, like rewrite this and make sure that it works for me.

That's what ChatGPT is good for, right? To do the boring stuff.

Like this is boring to me. I don't want to do that. I just want to make fun stuff. So it is actually a dialogue. So I'm not sure about accessibility if it's still correct. I'm using open and close and I'm not sure if it's okay. But yeah, that's kind of cool. Okay, let's get back to this one. This one.

I have no idea how long I've been talking, but it's fine.

Okay, so there's some pros and cons to a view transitions as well, of course.

For example, the native standardized functionality is great because we can be more sure that users will get a similar user experience across browsers.

There's no more math. Yay. Great.

You're not as excited. Okay, there's less JavaScript.

It's not no JavaScript in most cases, but it can be if you keep it simple. And that's also... the defaults are very good. So by default you get quite cool animations and only once you want to make more cool stuff, then it gets complicated and it gets complicated fast, to be honest. But things like scroll driven animation and keyframe animations, they don't matter. They are just done correctly because using JavaScript and Page Transitions and Scroll Trigger, it sometimes caused issues. So this is very good.

There are some restrictions because they are snapshots, not images. There's less control because it's not HTML anymore. The dev tools are quite a bit unstable. When you use view transition classes, you can't actually see the styles that you're putting on things.

I've tried multiple browsers. Please help.

Aspect ratios changes are very hard. Oh, this is a QR code to the code I just showed, by the way. If you're wondering. Aspect ratios are quite hard. But as I mentioned, Jake Archibald wrote a great article about that. And browser support still not great.

It's finally in Nightly, but I tried it out and it didn't work. I updated Nightly. I don't know. Please help. I talked about this yesterday, but I'm still not sure if it's possible. You can't manipulate the automatic transforms, as far as I know on the view transition groups.

I would love to be able to animate the X axis first and then the Y axis and then the size, but I think it's all at once and I would love that. Okay, show me - with JavaScript?

Yeah, I want to do it without JavaScript.

Okay, so some final notes. Creative development has always meant animation emotion to me, and I think it still will. But I've kind of been living in a JavaScript-shaped bubble and I've been kind of crawling out now.

And while preparing for this talk and speaking to a lot of other creative developers or people that call themselves creative developers, my perspective has started to change a little bit. Because for many people that I spoke to, it wasn't about animation or motion. It was more about design and emotion and user experience.

And that's kind of interesting. And it's also nice to know that creative development doesn't really depend on the medium. We can do it in JavaScript, we can do it in CSS and maybe even in the next thing. And it's not about the tools we use, it's about how we use them.

So that was it. Thank you.

I bribed my students to give me a standing ovation, but they're not doing it.

Come on, give her the standing ovation. You want the goods? Thank you.

Anyone can do loyal students. Loyal students. What's your name again? Yeah, I'm not sure. Can't remember after all that. Don't know what time it is, how long I spoke.

You did fine. You did good. Yeah, the timer started later, so I thought maybe it didn't work. We could probably use a couple million more questions like Miriam had, but I think we have some here. Okay. Yeah.

So Victor asks if there are any accessibility issues with view transitions? Yes. Well, I kind of skipped over that, but I use a lot of like 'prefers-reduced-motion' to be...

I set my view transition names within 'prefers- reduced-motion: no-preference' to make sure that when people have that setting active that they will just see a crossfade and not see all the elements moving. So there are some, maybe some other concerns, but I think it's kind of fine. I see Hiro looking at me like there are issues. There are issues.

Okay. Dion asks: "Do you need JavaScript for page transitions?" Not really.

If you want to do different page transitions for different pages, then probably, yeah, I think you don't need it, but it's nice to enhance it with JavaScript. You can do it without. You can do it without. Okay, okay. Fair. And Luke asks: "do the view transitions work the same on phones?" On phones, yeah. On Safari I think it does work. And on Android phones probably as well. Don't have an Android phone. Bad developer. Don't have a device app.

I do. We'll test. Yeah, cool. You can. Yeah, you can check. They work.

Yeah. Oh, they work. It's just like, yes. Things like scroll driven animations don't work on Safari yet. But I think most view transition things do work the same on Chrome and on Safari. Okay.

Yeah. Or iOS. Steven asks: "can you make my portfolio site for me for free?" We'll talk later. Okay.

Oh, no. One of the things I really love about what you do is it feels so playful.

It's very creative. We were talking yesterday and you said, "I'm not really a designer." But you kind of are a designer. You have an intention and you make something based on that. So you manifest that intention somehow. How could we, people who have more boring work, like some of us do, introduce more playfulness into - say if you work in a more corporate environment?

Yeah, I think there's time and place for animation, definitely. Like, I don't want to see like crazy view transitions on my dentist's website or something, but you can do like small micro interactions to make things more fun. And also I steal a lot from other people.

So in Dutch we say [speaks in Dutch] - doesn't translate to English I think? It's better if you steal it. Steal it well, than not steal it badly or something? Not think of it. And yeah, I don't know.

It doesn't translate. But that kind of... yeah, I really get a lot of inspiration from other developers. I'm part of this group called OKDev because we're not great. We're just okay, we're all just creative JavaScript developers and bro coding and stuff. Yeah, so that's my bubble. You said just now that you wouldn't want to see a lot of animations on your dentist site, for example. How would you...

do you have some criteria that you go through to figure out when is it appropriate, when is it not appropriate? I think like most people would be able to tell. Like I've seen too much animation on a lot of like corporate websites where they're doing like fade in animations and I'm like: Why? This doesn't add anything to, to the experience of the user. It's just because the developer is bored in their job. Get a new job, go freelance, go back to school.

Do you think all animation has to be functional? Could you just add something frivolous in there? Yeah, like coming in from the side. Stephen says add nonsense, you can add nonsense, but I think it should be appropriate. Like on a government website. You don't want to have everything animating and stuff. Yeah. Okay.

What do you find to be the most frustrating thing about View Transitions?

Yeah, pretty much the DevTools at this moment, but I think might be my device. But I've tried in multiple Chrome versions and it's kind of hard to debug. Yeah, probably that. But otherwise I'm really happily surprised by how easy they've made a lot of things that were very hard to do. So mostly very happy. Mostly happy.

Okay, fair enough. And are there things with CSS in general that you haven't tried yet that you're really interested in trying?

Anchor Positioning, but yeah, I'm really excited about that. But it's not supported well enough to even kind of use it in production. So yeah, I'm excited about it, but needs a little bit more time for me to start using it, I think. How would you describe your work? Do you feel... I know you call yourself a creative developer, which I guess is the same as creative coder or. I guess. Yeah, yeah, it's all made up.

Okay. Yeah, right, fair enough. Like all of our titles are.

But do you - have you tried something that's beyond a website?

Say art? I would love to do an installation.

So if anyone wants to pay me to create an installation, hit me up.

I would love that. You could do it for free if you want. I could maybe.

Exposure. Exposure, yeah. I'm too old for that.

All right, well, do we have any more questions here? No, I don't think we do. So I think I just want to say thank you for your inspiring work. I love all that kind of stuff, and it's the kind of thing that I would love to be able to do, and I feel like it's so far removed from what I do on a daily basis that it just really inspires me. I think a lot of people here, you agree? Yeah. Pretty cool stuff.

We all want. We all kind of want your job. Oh, yeah.

We can switch jobs for one day if you remember my name. Yeah.

This is. I'm never going to hear the end of this. Yeah.

She said you're never going to forget now. Yeah. Well, thanks for not being mad at me about that. Yeah. And thanks for your talk and for joining us today. Thank you. Cyd Stumpel.

CSS CAME FOR MY JOB

(A practical guide to view transitions for creative developers)

Website: cvdstumpel.nl — Socials: @cvdstumpel

Photograph of a person holding large gold letter balloons spelling "CYD". Behind them are stylized, partially visible purple balloon-like letters on the slide background. In the lower corner, the website "ovdstumpel.nl" and social handle "@ovdstumpel" are displayed as text.

Doe Mee Groei Ontmoet

Screenshot of the BROED event website featuring large blue abstract shapes as background and text promoting events and workshops for creative professionals in November 2024.

OMG WE'RE 10
2013-2023
How it all happened

Illustration of a distorted three-dimensional head with floating digital interface elements, used as a visual for a 10-year anniversary (2013-2023) celebration.
Screenshot of a website interface showing interactive cards with user profiles, awards, and project titles against a starry space-themed background. One card is labeled "WOGAN Honourable Mention" and another "Leave no Crumbs"; user profile cards for "FFION" (Marketing) and "ALEX" are also visible.

Visdeurbel

Screenshot of the Visdeurbel (Fish Doorbell) website home page.

Visdeurbel

Screenshot of the Visdeurbel website interface, featuring a large interactive button and a webcam live stream feed.

Visdeurbel

Screenshot of the Visdeurbel website, partially covered by a vertical video clip featuring a John Oliver speaking.

PARTTIME TEACHER

RAY CHARLES VIDEO MUSEUM

Screenshot of a website featuring a card with a photo of Ray Charles and Kermit the Frog.

Tweet about updating a portfolio website

Screenshot of a tweet announcing a portfolio website update, including an embedded video or image showing a website with the text: "Transporting you to the 17th century" and a historical painting.
Screenshot of two social media posts: one showing the phrase "CREATIVE DEVELOPER" in large text, and another discussing portfolio explorations.
Photo of a coffee mug with the text "CSS DAY IS AWESOME" next to an open laptop.

CSS Came For My Job

CSS CAME FOR MY JOB

THE BORING & HARD PARTS OF
A blue diamond shape is displayed toward the right side of the slide against a blank background.

Our Brands

Screenshot of a website section titled "Our Brands" showing images of bicycles and related products.

RIDE OUT

Screenshot of a bicycle shop website featuring the brand Cannondale, with sections showcasing bike close-ups and navigation links including Webshop, Services, Events, Brands, About us, and Contact.

FOCUS Bikes

Screenshot of the Ride Out bike shop website homepage featuring FOCUS Bikes and the slogan "Ride together, ride beyond", with a blurred bicycle in the background.

Pros/Cons

  • Full creative control

Pros/Cons

  • Full creative control
  • Still HTML

Pros/Cons

  • Full creative control
  • Still HTML
  • Able to handle WebGL animations
  • Complicated setup
  • Lots of calculations and code

Pros/Cons

  • Full creative control
  • Still HTML
  • Able to handle WebGL animations
  • Complicated setup
  • Lots of calculations and code
  • PopState/resize causes issues

THE WEIRD STUFF

  • FULL PAGE NAVIGATIONS

THE WEIRD STUFF

  • FULL PAGE NAVIGATIONS
  • KILL PROCESSES
  • THIRD PARTY SCRIPTS
Abstract illustration resembling a blurred bouquet of colorful flowers centered on the slide.

View transitions

DOUANE

Screenshot of a photography portfolio website displaying a photo of a woman being interviewed outdoors, with thumbnails of other photos below.

LEGO

Screenshot of a website displaying an image of the LEGO logo rendered in the sky with illuminated drones above a city skyline.

Filter: All Cinematography Color grading Photography

Screenshot of a photography portfolio website displaying a grid of six photographic works including portraits, outdoor scenes, and creative visuals.

SPAs MPAs

RFWS


				@view-transition {
					navigation: auto;
				}
				
document.startViewTransition(() => {
					filterItems();
				});
Diagram showing two wireframe-style website layouts: on the left, a grid of four square cards with captions beneath each; on the right, a layout with a larger square area to the left and several lines representing text on the right, suggesting a content shift or layout change between two page states.
Diagram of a hand cursor clicking on the first item in a horizontal row of four card-like elements, suggesting a selection or interaction in a user interface.
Diagram with a large filled square on the left and several horizontal bars of varying lengths on the right, representing a wireframe for a layout with an image and lines of text.
Diagram showing two interface wireframes: on the left, a horizontal row of four card elements each with an image and text underneath; on the right, a layout with a large square image on the left and several horizontal text lines on the right, representing a detail or expanded view.

SIMPLE EXAMPLE

View transitions

Screenshot of a web page demonstrating view transitions, with the browser's developer tools showing the Animations panel open.

About View transitions

Screenshot of a web page titled "About View transitions" displayed in a browser next to browser developer tools showing styles for a view-transition-group element.

About View transitions

Screenshot of a web page titled "About View transitions" displayed alongside a browser developer tools panel showing HTML and CSS related to view transitions.
Two wireframe-style illustration diagrams: on the left, a box containing four vertically-stacked rectangular cards in a row, each with a title and short description; on the right, a larger box with a main square image or block on the left and multiple lines of text/content stacked to the right, suggesting a different structural layout.
<img src="example.jpg">

				img {
					view-transition-name: image;
				}
				

				
				

				img {
					view-transition-name: var(--vt);
				}
				::view-transition-old(image-1) {
					animation: none;
				}
				::view-transition-old(image-2) {
					animation: none;
				}
				::view-transition-old(image-3) {
					animation: none;
				}
				
<img src="example.jpg" style="--vt: image-1">
				<img src="example.jpg" style="--vt: image-2">
				<img src="example.jpg" style="--vt: image-3">
				

				img {
					view-transition-name: var(--vt);
				}
				::view-transition-old(image-1) {
					animation: none;
				}
				::view-transition-old(image-2) {
					animation: none;
				}
				::view-transition-old(image-3) {
					animation: none;
				}
				
<img src="example.jpg" style="--vt: image-1">
				<img src="example.jpg" style="--vt: image-2">
				<img src="example.jpg" style="--vt: image-3">
				

				img {
					view-transition-name: var(--vt);
				}
				::view-transition-old(image-1) {
					animation: none;
				}
				::view-transition-old(image-2) {
					animation: none;
				}
				::view-transition-old(image-3) {
					animation: none;
				}
				
<img src="example.jpg" style="--vt: image-1">
				<img src="example.jpg" style="--vt: image-2">
				<img src="example.jpg" style="--vt: image-3">
				

				img {
					view-transition-name: var(--vt);
					view-transition-class: image;
				}
				::view-transition-old(.image) {
					animation: none;
				}
				
<img src="example.jpg" style="--vt: image-1">
				<img src="example.jpg" style="--vt: image-2">
				<img src="example.jpg" style="--vt: image-3">

				img {
					view-transition-name: var(--vt);
					view-transition-class: image;
				}
				::view-transition-old(image) {
					animation: none;
				}
				
<img src="example.jpg">
				<img src="example.jpg">
				<img src="example.jpg">
				

				img {
					view-transition-name: match-element;
					view-transition-class: image;
				}
				::view-transition-old(.image) {
					animation: none;
				}
				
<img src="example.jpg">
				<img src="example.jpg">
				<img src="example.jpg">
				

				img {
					view-transition-name: match-element;
					view-transition-class: image;
				}
				::view-transition-old(.image) {
					animation: none;
				}
				
window.addEventListener('pagereveal', async (e) => {
					if (e.viewTransition) {
						const fromURL = getFromUrl(navigation)
						const toURL = getToUrl(navigation)
		
						if (fromURL.includes('overview') && toURL.includes('/work')) {
							e.viewTransition.types.add('overview-to-work')
						}
					}
				});

				html:active-view-transition-type(overview-to-work) {
					&::view-transition-group(root) {
						animation-duration: 0.1s;
						animation-fill-mode: both;
						animation-timing-function: ease-in;
					}
				}
				
window.addEventListener('pagereveal', async (e) => {
					if (e.viewTransition) {
						const fromURL = getFromUrl(navigation)
						const toURL = getToUrl(navigation)
						if (fromURL.includes('overview') && toURL.includes('/work')) {
							e.viewTransition.types.add('overview-to-work')
						}
					}
				});

				html:active-view-transition-type(overview-to-work) {
					&::view-transition-group(root) {
						animation-duration: 0.1s;
						animation-fill-mode: both;
						animation-timing-function: ease-in;
					}
				}
				
window.addEventListener('pagereveal', async (e) => {
					if (e.viewTransition) {
						const fromURL = getFromUrl(navigation)
						const toURL = getToUrl(navigation)
		
						if (fromURL.includes('overview') && toURL.includes('/work')) {
							e.viewTransition.types.add('overview-to-work')
						}
					}
				});

				html:active-view-transition-type(overview-to-work) {
					&::view-transition-group(root) {
						animation-duration: 0.1s;
						animation-fill-mode: both;
						animation-timing-function: ease-in;
					}
				}
				
window.addEventListener('pagereveal', async (e) => {
					if (e.viewTransition) {
						const fromURL = getFromUrl(navigation)
						const toURL = getToUrl(navigation)
		
						if (fromURL.includes('overview') && toURL.includes('/work')) {
							e.viewTransition.types.add('overview-to-work')
						}
					}
				});

				html:active-view-transition-type(overview-to-work) {
					&::view-transition-group(root) {
						animation-duration: 0.1s;
						animation-fill-mode: both;
						animation-timing-function: ease-in;
					}
				}
				
Screenshot of a user interface grid displaying numbered tiles from 1 to 8, with an "A-Z" filter or sorting option visible.
Diagram of a UI grid displaying eight numbered tiles (1-8) in two rows, with a control at the top left showing "A-Z" and a hand cursor clicking it. The diagram illustrates sorting or filtering UI interaction.
Diagram showing a user interface with a hand cursor selecting an "A-Z" sorting option above a grid of numbered tiles (2, 1, 6, 4, 5, 8, 3, 7), representing sortable items.
Diagram showing a grid of six purple squares numbered 1, 6, 4, 5, 8, and 7, with a UI element at the top left labeled "A-Z" and toggle buttons, one of which is being "clicked" by a pointing hand cursor. The arrangement suggests sorting or filtering functionality in a graphical interface.
Diagram showing an interactive visual sort where a toggle labeled "A-Z" is being activated. Multiple numbered boxes (1, 2, 3, 4, 6, 7, 8) are visually reordered within a grid. Some boxes have colored outlines indicating animation states or changes, and a hand cursor illustrates the toggle action.

View transitions sorting and filtering - commented

Screenshot of a CodePen interface showing a code editor with CSS and JavaScript for sorting and filtering, alongside a grid of historical photographs of women in technology.

View transitions sorting and filtering: commented

Screenshot of a CodePen interface showing a demo titled "View transitions sorting and filtering: commented" with a media grid of historical women in technology, and code panels for HTML, CSS, and JavaScript on the right.

View transitions sorting and filtering - commented

Screenshot of a code editing environment showing an HTML/CSS/JS code playground with a grid of seven historical women's portraits and a visible JavaScript code editor on the right.

View transition sorting and filtering - commented

Screenshot of a web application for sorting and filtering images of women in computing history, with code editor panes showing HTML, CSS, and JavaScript code.

View transitions sorting and filtering - commented

Screenshot of a CodePen editor displaying a web page grid of historical women, with form controls for filtering and sorting, and showing associated HTML, CSS, and JavaScript code panels.

View transitions sorting and filtering - commented

Screenshot of a code playground/editor showing an interactive grid of historical women along with HTML, CSS, and JavaScript code that implements sorting and filtering with view transitions.

View transitions sorting and filtering - commented

Screenshot of a CodePen interface featuring a demo for filtering and sorting images with CSS and JavaScript, including filter dropdowns and a row of black and white portrait images.

View transitions sorting and filtering - commented

Screenshot of the CodePen editor displaying a demo of view transitions with image sorting/filtering UI, a grid of historical women in technology photos, CSS and JavaScript code panels, and select dropdowns to sort/filter the images.

View transitions sorting and filtering - commented

Screenshot of a CodePen interface displaying an HTML form with sorting/filter controls, a CSS grid of six historical women's portraits, and code panels for HTML, CSS, and JavaScript related to view transitions functionality.
Screenshot of a CodePen web application for sorting and filtering images with view transitions. The interface displays a grid of historical figures' portraits and includes code panels for HTML, CSS, and JavaScript related to view transitions and grid interactions.

View transitions sorting and filtering - commented

Screenshot of a CodePen project showing a grid of historical women in STEM, with code for handling view transitions and animations in CSS and JavaScript.

View transitions sorting and filtering - commented

Screenshot of a CodePen editor. The left side of the slide shows a user interface for sorting and filtering a grid of historical photographs of women, including scientist, actor, and programmer figures. The right side shows HTML, CSS, and JavaScript code implementing view transitions for the grid.

View transitions sorting and filtering - commented

Screenshot of a CodePen interface showing a demo for sorting and filtering with view transitions. The demo displays a grid of black and white and color photographs of women, a code editor with HTML, CSS, and JavaScript code for transitions, and dropdown menus labeled "Default Media Type" and "No sorting".

View transitions sorting and filtering - commented

Screenshot of a web-based code editor (CodePen) showing an interface for sorting and filtering a grid of historical women's photos, with HTML, CSS, and JavaScript code panels visible on the right.

THE FUN STUFF

Photo grid of four conference speakers, partially visible behind the main slide content.
Screenshot of a website for an event with a code block describing event details, and a grid of speaker portraits, highlighting Brad Frost as a featured speaker.
Screenshot of a conference event website for CSS Day 2025, featuring a grid of speaker photos and event details in code-like style.
Screenshot of a web page for a conference speaker profile, showing a large photo of Adam Argyle, CSS code for the talk details, and descriptive information about the talk and speaker.

				:root {
					--ease: cubic-bezier(0.12, 0.39, 0, 0);
					--ease-out: cubic-bezier(0.61, 1, 0.88, 1);
					--elastic-ease: cubic-bezier(0.34, 1.56, 0.64, 1);
				}
				/* ... */
				html::view-transition-group(*) {}
				html::view-transition-old(*) {}
				html::view-transition-new(*) {
					animation-fill-mode: both !important;
					animation-timing-function: var(--ease);
				}
				/* 1. Setting view-transition names if user has no preference for reduced motion */
				@media (prefers-reduced-motion: no-preference) {
					[style^="--vt"] {
						view-transition-name: var(--vt);
					}
				}
				/* 2. set view-transition-names and class for title and talk title */
				/* ... */
				
VS Code editor showing a CSS file (view-transition.css) with custom view transition styles and media queries for animation timing.

hover-animation.js → view-transitions

const speakerCards = document.querySelectorAll('.speaker-card');
		
				if (speakerCards) {
					const title = document.querySelector('.speakers .title');
					const talkTitle = document.querySelector('.speakers .talk-title');
					// not chat, it's general
					speakerCards.forEach((speaker) => {
						speaker.addEventListener('mouseenter', () => {
							const name = speaker.dataset.name;
							const talkTitleText = speaker.dataset.talkTitle;
							// If the title is already new to the hovered name, return
							if (title.textContent == name) {
								return
							}
							// 1. check if view transition is supported
							// 2. start view transition
							// 3. add view transition type
		
							title.textContent = name
							talkTitle.textContent = talkTitleText
						})
					})
				}
VS Code editor showing a JavaScript file (hover-animation.js) that implements a hover animation for speaker cards using event listeners and view transitions.

hover-animation.js → view-transitions

speakerCards.forEach((speaker) => {
					speaker.addEventListener('mouseenter', () => {
						const name = speaker.dataset.name;
						const talkTitleText = speaker.dataset.talkTitle;
						// if the title is already == to the hovered name, return
						if (title.textContent == name) {
							return;
						}
						// 1. check if view transitions is supported
						// 2. start view transition
						// 3. add view transition type
				
						title.textContent = name
						talkTitle.textContent = talkTitleText
					});
				});
				
VS Code editor showing a JavaScript file implementing a hover animation with view transitions.

hover-animation.js → view-transitions

speakerCards.forEach((speaker) => {
					speaker.addEventListener('mouseenter', () => {
						const name = speaker.dataset.name;
						const talkTitle = speaker.dataset.talkTitle;
						// if the title is already = to the hovered name, return
						if (title.textContent === name) {
							return
						}
		
						// 1. check if view transition is supported
						if (document.startViewTransition) {
		
						} else {
							// ...
						}
		
						// 2. start view transition
						// 3. add view transition type
		
						title.textContent = name;
						talkTitle.textContent = talkTitleText;
					});
				});
				
VS Code editor showing a JavaScript file (hover-animation.js) with code handling speaker card hover interactions and conditional use of view transitions.
VS Code editor showing JavaScript code implementing view transition logic for updating a presentation title and talk title when a speaker card is hovered over.

hover-animation.js – view-transitions

types: []
				
VS Code editor showing JavaScript code in the file hover-animation.js, which is implementing view transitions and handling mouse events.
Screenshot of a web page promoting the CSS Day 2025 conference, featuring headshots of speakers.
Screenshot of the VS Code editor showing JavaScript code for view transitions in a file named "hover-animation.js".

				html: view-transition-new(*){
					animation-fill-mode: both !important;
					animation-timing-function: var(--ease);
				}
				/* 1. setting view-transition names if user has no preference for reduced motion */
				@media (prefers-reduced-motion: no-preference) {
					[style*="--vt"] {
						view-transition-name: var(--vt);
					}
				}
				/* 2. set view-transition-names and class for title and talk title */
				.title {
					view-transition-name: title;
				}
				.talk-title {
					view-transition-name: talk-title;
				}
				.large-titles .title,
				...
				
VS Code editor showing CSS code for configuring view transitions, including animation and reduced motion settings.

				/* 1. setting view-transition names if user has no preference for reduced moti */
				@media (prefers-reduced-motion: no-preference) {
					[style*=--vt-] {
						view-transition-name: var(--vt-);
					}
				}
				/* 2. set view-transition-names and class for title and talk title w/ */
				.title {
					view-transition-name: title;
				}
				.talk-title {
					view-transition-name: talk-title;
				}
				.large-titles .title,
				.large-titles .talk-title {
					view-transition-class: text-animation;
				}
				
VS Code editor showing a CSS file that configures view transitions for titles and talk titles in a web project.
VS Code editor window showing the file view-transition.css with CSS code for view transitions, overlaid on a browser preview with event information for "CSS Day".
Screenshot of VS Code editor showing CSS code for view transitions, with an adjacent browser preview of a slide titled "Adam Argyle Level up your scroll UX".
VS Code editor showing CSS code for view transitions, with the file 'view-transitions.css' open. In the background, a web browser window shows an event information page for "CSS Day" including date, location, and speakers.
Screenshot of VS Code editor showing CSS code for view transitions and a partial web browser window listing CSS Day event details.
VS Code editor showing a CSS file named view-transitions.css with animation keyframes for view transitions. To the left, a partial website preview for "CSS Day" is visible.
Screenshot of the VS Code editor showing CSS code for view transitions, overlaid on a browser displaying an event page titled "Level up your scroll UX" by Adam Argyle.
Screenshot of the VS Code editor showing a CSS file named view-transitions.css with code related to view transitions. The background also shows a browser preview with event information for "CSS Day" and a heading "John All… A Dao of CSS".
Screenshot of the VS Code editor showing a CSS file (`view-transition.css`) with code for keyframes animation and view transition rules. A browser window in the background displays event information for "CSS Day" with dates, location, and a list of speakers.

Screenshot of VS Code showing view-transition.css

Screenshot of the VS Code editor window with the file "view-transition.css" open, displaying CSS code related to view transitions. In the background, a browser window shows an event page for "CSS Day" including dates, speakers, and location.

CSS Day

  • 5–6 June 2025 | Amsterdam — NL
Screenshot of a VS Code editor showing JavaScript code for handling page transitions, alongside a browser preview of a CSS Day event page.

CSS Day

5–6 June 2025 | Amsterdam — NL

Screenshot of a code editor (VS Code) open to the file view-transition.css, displaying CSS code related to speaker card styling, alongside a preview of a local website for a CSS conference called "CSS Day" with event details.
Screenshot of a code editor (VS Code) showing a CSS file named "view-transitions.css" with code for styling view transitions, overlaid on a partially visible presentation slide titled "Level up your scroll UX" by Adam Argyle.

What is CSS Day?


				.css-day-2025 {
					date: 5th and 6th of June;
					speakers: 15 in one track;
					location: Amsterdam – NL;
				}
				
Screenshot of the VS Code editor showing a CSS file with transition animations.

view-transition.css


				/* The nasty stuff   */
				/* Would love to be able to do this with sibling index somehow */
				.view-transition-group(stephen-hay) {
					--index: 0;
				}
				.view-transition-group(rachel-andrew) {
					--index: 1;
				}
				.view-transition-group(ahmad-shadeed) {
					--index: 2;
				}
				.view-transition-group(adam-argyle) {
					--index: 3;
				}
				.view-transition-group(brad-frost) {
					--index: 4;
				}
				.view-transition-group(tim-nguyen) {
					--index: 5;
				}
				
VS Code editor window showing a CSS file for view transitions, with highlighted code for assigning index variables to different transition groups. Other application windows and file explorer are visible in the left panel.

				/* 5. when the old speaker card is an only child it means it wasn't animated out */
				&.view-transition-old .speaker-card:only-child {
					animation-name: scale-out;
					animation-duration: 0.3s;
					animation-delay: calc(var(--index) * 0.03s);
				}
				/* 6. when the new speaker card is an only child it means it wasn't animated in */
				&.view-transition-new .speaker-card:only-child {
					animation-name: scale-in;
					animation-duration: 0.3s;
					animation-delay: 0.3s;
				}
				
Screenshot of the VS Code editor showing CSS code for view transitions, alongside a browser preview for a CSS Day event page.
VS Code editor showing CSS code for view transitions alongside a browser window displaying event information for "css-day.2025", including event dates, location, and speaker details.

view-transition.css → view-transitions

Screenshot of the VS Code editor showing a CSS file with code related to view transitions, alongside a browser preview panel displaying CSS Day conference information.
VS Code editor showing a CSS file with animation and transition variables for view transitions, alongside a browser preview displaying event information for "css-day 2025" and a speaker name.

CSS Day

Screenshot of a code editor (Visual Studio Code) showing the file view-transition.css with CSS code and a browser window displaying event information for CSS Day 2025.
VS Code editor showing a CSS file open with code related to view transitions and animation delays. Part of the slide shows a local web browser preview with event details for "CSS Day" including date, speakers, and location.
Screenshot of the VS Code editor showing CSS code in a file named view-transitions.css, with a web browser preview and a sidebar of project files visible.

CSS Day

  • 5–6 June 2025 | Amsterdam – NL
  • edited 5th and 6th of June;
  • speakers: 15 in one track;
  • location: Amsterdam – NL;
VS Code editor showing a CSS file with SCSS code for animating code property values and punctuation with view transitions. The slide also shows a browser preview window of a "CSS Day" event listing on the left side.
Screenshot of the VS Code editor showing CSS code for view transitions, with a browser window in the background displaying CSS Day 2025 event information.
Screenshot of the VS Code editor showing CSS code in the file "view-transitions.css", alongside a browser window previewing a local site for "CSS Day" with event details.
Screenshot of the VS Code editor showing a CSS file with code implementing view transitions, alongside a browser window with details about CSS Day 2025.
const trigger = document.querySelector('.info-trigger')
				const dialog = document.querySelector('dialog')
				const draggable = document.querySelector('.info-trigger')
		
				// Track drag
				let startY = 0
				let latestY = 0
				let currentProgress = 0
				let activeAnimtation = null
				let dialogHeight = 0
				let isOpening = false
		
				const watchDragOpening = async (downEvent) => {
					startY = downEvent.pageY
					latestY = startY
					currentProgress = 0
		
					const controller = new AbortController()
		
					// Start the view transition and wait for it to be ready
					const dialogState = isOpening ? 'dialog-closing' : 'dialog-opening'
					const openTransition = document.startViewTransition(() => {
						update()
						document.documentElement.classList.add('grabbing')
					})
					...
				
VS Code editor showing JavaScript code for drag tracking and dialog transition logic.

John A

A Dao of CSS

  • .css-day-2025 {
    • date: 5th and 6th of June;
    • speakers: 15 in one track;
    • location: Amsterdam – NL;
    }
VS Code editor showing JavaScript code for gesture handling, including a function watchDragging in the file gesture.js for handling pointer movement and progress calculations, alongside a sidebar showing project folders and files.
Screenshot of the VS Code editor showing JavaScript code for handling view transitions, alongside a preview window displaying event details for "css-day 2025" with date, speakers, and location.
VS Code editor showing JavaScript code for dialog handling in a file named gesture.js. In the background, part of a website or slide titled "CSS Day" is visible, with event details and the text "John AT".

PROS/CONS

  • Native, standardized functionality
  • No more math
  • Less JS
  • Good defaults
  • ❌ Some restrictions
  • ❌ Less control
  • ❌ Dev tools are still a bit unstable
  • ❌ Aspect ratio changes are hard
  • ❌ Browser support
  • ❌ Can't manipulate the automatic transforms
https://noti.st/kitten/QR

CREATIVE DEVELOPMENT

THANK YOU

  • View Transitions
  • FLIP Animation Technique
  • Swup Library
  • WebGL Animations
  • GSAP (GreenSock Animation Platform)
  • @view-transition { navigation: auto; }
  • document.startViewTransition
  • Animations Panel in Developer Tools
  • ::view-transition-group
  • view-transition-name
  • match-element
  • pagereveal Event
  • prefers-reduced-motion Media Query
  • CSS Variables for View Transitions
  • Cubic Bezier Timing Functions
  • CSS Mask-Image Property
  • :only-child Pseudo-Class
  • AbortController in JavaScript