 Should we do? Should we do that? No, no, that happens, though. I still, I don't know, are we rolling? Yeah. Cool. All right. Did I unmute myself? Yeah. Blah, blah, blah, blah, blah, blah, blah, blah, blah, blah. Cool. How unprofessional do you think Lucas is? You're going to get through the whole thing and it's like, oh, and Serma didn't say much in that episode. I want to talk about this. Cross fading DOM elements. Yep. Yeah. Have you heard of CSS opacity? I have and watch me use it. Are you ready? Yes. Hey. Job done. Ship it. Okay. That is easy because one of the elements is opaque and covers the other one. Like cross fading is easy on the web when that's the case. And that's what I had there. As opposed to when there's opaque. Oh, I feel like there's no transparency in the visual you're fading in. Yes. Because I've got an element. It's got the blue gradients. I've gone from the yellow gradient and other elements over the top. And I've just gone from opacity zero to opacity one. Job done. That's actually, it's a good cross fade. It works. Yeah. But done, done, done. Jake with his checkered backgrounds. Yep. Pretty much everything I work on ends up with a checkered background at some point. And this is no exception. So the same trick from before does not work here. Because... Just like fading on on top. Yeah. Right. Clearly it's not. Come on, we're all learning things, right? So when I have been faced with this situation, what I've done is, well, I've got to fade the other one out as well. Yeah. Double opacity. One, you know, the good there is going to go from opacity one to opacity zero. And then the other one... Yeah, come to the back. I'll do it. Okay, okay. It's pretty good. No. No, that wasn't good. Look at it. It's horrible. But the bit to look out for is the G and the O, which is the same in both. It fades out and then fades again. Oh, there's a bit of checkered background. So if I like his... I think I'm too distracted by the OATD stuff that I don't notice that. So I feel like you can just ship it. No. I want to know. End of episode. Shut up. I want to do this properly. Okay. So the thing is that there's some... A bit of like a whoop whoop from under the first one that said it should be the same and should stay constant. Yes. And it's wrong... So this is the 50% mark. It shouldn't be transparent on the G and the O because it's the same. So it shouldn't change during the crossfade. But also the intersection of the A and the O and the T and the D should be... They shouldn't be see-through. Oh, because like they're both at 50% and you want... Basically you're not saying that should be 50% and translucent. They should take up 50% of the visual. But... I have no idea what you're all about. Ah, never mind. It's wrong and we're going to fix it. We're going to fix it. You could just split the word in half. Do you know what? I posted this online and that's what someone did. And I was like, it's still wrong because the intersection on the A and the O is wrong and the T and the D is wrong. And I'm... Look, the reason it's not working is because of how layering works on the web and everything else like Photoshop and all that. So they use the same basic rule. Whereas if they... Here's a square with opacity 0.5. And what that does is that's going to block out 50% of the background. And when you do this, you've put another one on top, that's going to block out 50% of the background. But if we end up with 75%? Exactly, yeah. If you halve something, halve something again, you end up with a quarter remaining. And so, yeah. In this case, the equivalent is opacity 0.75. Which is correct for layering. Yes. But it is not correct for a crossfade, which is what you're trying to achieve. Which is what we're trying to achieve. So I'm going to have a look into how this works mathematically. Because this is something that's happening with thousands and thousands of pixels at once. But it's actually quite a lengthy process to figure out how to put one pixel on top of another pixel and figure out what they... Yeah, I actually have no idea how intuitively how to fix that because if you always just talk about how much to let through of the background, the second they both let anything through, the background will come through. They can never add up to no background is coming through. So here's how normal layering works. So what we're going to do is take a red 50% opacity pixel and we're going to put it on top of a blue 50% opacity pixel. So let's take a look at the first thing we do. The first thing we do is multiply the colors by their alpha. Often called pre-multiplied, isn't it? Pre-multiplied alpha. Which is the kind of default language for like some webGL. Computer graphics and stuff, I think. But it's not something we encounter elsewhere on the web often. Like when we're doing colors in CSS, they're not pre-multiplied. 2D canvas is not pre-multiplied. WebGL can be either. And I think it is... I only note as a necessity for compositing. Compositing, when you have multiple layers and you want to merge into one image, if you don't do this, then layers with transparency can get weird fringes. Yes, and that's exactly why we're going to multiply them here. Because we're going to be doing some compositing. I guess it is compositing, yeah. So the operation we're about to do is called Source Over. Which is one of the compositing methods. Duffner, Albert. The Duffner, Albert. Compositing. PortaDuff. PortaDuff, thank you. People who define this sort of stuff. So we've got our two multiplied pixels, the source and the destination. And this is the bit which is key for the Source Over operation. What they do is they take the pre-multiplied destination and multiply every channel, the red, green, blue and alpha, by one minus the alpha of the source. Oh, and this reduces the impact of the destination. The final destination. The final destination. And then they're just added together. So now we're taking that transformation and we're adding all of the channels of that to the channels of the source. Also it's two steps. The first step is literally just like adjusting by one minus the alpha of the source and then as a separate step you add them together. It's okay. Yes. And then we're going to un-multiply. Un-multiply. You mean like division? Division. I couldn't. Yeah, I mean that would be the right term for it. Let's go with un-multiply. Where we are going to take all of the channels and we're going to divide them by the alpha to get the kind of value that we are more familiar with. And that's the result. So we can see here that we've got the 0.75 alpha, which is wrong for a crossfade. We would want it to be one. But the colors are also not what we would expect for a crossfade because we've ended up with like one-third red and two-thirds blue. Yes. If you would want to be slap bang in the middle purple, right? Exactly. You would want 50 percent, 50 percent in a crossfade, halfway through a crossfade. So it's kind of wrong not just on the alpha but also on the color as well. And things kind of went wrong. So why did you show me all this? This is wrong. Well I'm showing you why it's wrong. Like this is, but this is correct for layering. Right. Because we were doing that reduction on the destination, which is the thing in the background, but not on the source, which the result of that visually is that the order matters. Something is on top of the other thing, right? Right. So the only difference between these two is that on the left hand side, the blue is on top, on the right hand side, the red is on top. You might think intuitively that 50 percent alpha order wouldn't matter, but exactly because of the reason, like you're going from the background forwards, I guess, how much is led through from what is behind you, the order does matter. Yes, exactly. Which is correct for layering, it's just not correct for crossfading, because in a crossfade the order doesn't matter at all. Like it doesn't matter because it is just like a linear interpolation of, you know, one pixel to another pixel. So there is a solution in CSS for this. Dash webkit dash crossfade. Yes, it's defined in CSS as crossfade, but the only browsers that implement it are Chrome and the Chromium browser and the WebKit browsers. It was implemented many years ago, back when we used to use these prefix things, and there isn't a prefix, an un-prefixed version yet, Firefox doesn't support it either, but this lets you provide two images and then a percentage. A fixed percentage, like can you animate the percentage? You can, and this will animate, yeah, because it's got a transition on background image, and then you hover it and it will be fading from one to the other. This feels like this would repaint, even though there's probably a way to do it without repaints, but we're ahead of... Yes, I don't think it's an optimized implementation in terms of that, but it works, right? So it's not a full solution because you have to do it with images, you can't do it with just DOM elements, but you'll do this, and that's where you see that's a proper crossfade because the O, the G and the O at the start, even though it is crossfading them, because those pixels are the same between the images, there's no visual difference. And also, if we go to 50% of the transition, you can now see the bits where the O and the A intersect, and the T and the D intersect, you've got a solid color. Okay, so what's the math behind this then? It's a different compositing method that is also in the Schubert Cumberdale book of compositing methods. It's called lighter. So the one we saw before, the one that is a layered one, doesn't work crossfade, source over, this one is lighter. That's what we're actually doing in the implementation for crossfade. The spec doesn't say you have to use lighter for this. The spec talks about a linear transition of colors. Oh, that also makes sense to talk about as like your linear transition from the first pixel value to the second pixel value. It doesn't, it doesn't. Actually, I can't quite remember what the spec words it like, but if you just define it as a linear transition of colors, you run into the problem of if you go from zero opacity black to 100% opacity white, you'll get the gray in the middle because your red, green and blue are interpolating from zero to 255. Also true. But that is not true in premultiplied colors because there's no, you never have a case where you have a, you know, an alpha of zero and anything else. Yeah, you go from blue zero percent opacity. Like the premultiplication will effectively turn it black even though it's actually blue. Yeah, exactly. Okay, I can see the problem. So that's one of the reasons like we would use premultiplied colors for this, right? Yeah. And that's what, what lighter does. So lighter is very similar to the previous operation. You know, start off with our colors, we multiply the alpha and then we just go and add them together. It doesn't have that transform step where we reduce the destination. And so that's where then the opacity also adds back to one. Yes. So if our opacities add to one, we will have that they always, when they overlap, they will have no full opacity, no transparency. Yeah, I'm struggling with the words as well. But it's like, yeah, one, one alpha. It's one opacity of a hundred percent in CSS terms. I, you know, we would multiply, it doesn't actually matter for this one because we're at one at one anyway. But that might not be the case. True. If the image has its own opacity in it. And I guess with the images we saw before, like the anti-aliasing on the letters mean there will be pixels which are. That's true, actually, yeah. Which are semi-transparent. And that's it. That's the solution we're looking for. So for shared element transitions, it's a feature where we want to bring page transitions to the web. We want proper crossfades. They're going to happen all over the place. And there might be a, you know, opacity in some of the elements. So we want to bring this to the web. The truth is actually already is there in some places. This is 2D canvas. Yeah. You have actually all the compositing operations as keywords there. You can do these shenanigans. So this would be doing a crossfade mix of two images in canvas that, you know, the magic bit there being the global composite operation, setting that to lighter. That's already there. So yeah, we just, we want to bring this to CSS so you can do if any two DOM elements. You don't have to do that hacky crossfade that doesn't quite work. And this seems like the right place for it. Because this is a bit of CSS where you apply a compositing operation to an element. So why not just lighter instead of multiply? Yeah. We already have mixed blend mode. Yes. Mixed blend mode is already a feature. It's just a keyword that's missing. Well, I guess I'd rather like it. Well, part of the question is, and one of the things, because we are proposing this to the CSS working group and saying, like, you know, can we have this for crossfading reasons but also for other things. The spec does define blending and compositing differently. In the global compositing operation thing in Canvas, they're all just thrown into one bucket. Yeah. So we're kind of like, is there a reason that compositing and blending was kept separate in CSS? We don't know the answer yet. They're going to have mixed compositing mode on there. Maybe. And, you know, are there cases where you would do both? You would blend in one way and composite in another way? Is that the, because blending doesn't change the alpha channel. Yeah. Is one of, is kind of the key difference between blending and compositing, I guess. I don't want to ask because I was like, I'm now not so sure anymore and I know the difference. No, I'm not sure I know the difference. I think it's something to do with what happens with the alpha channel. But it might not matter. And we can just do this and then you'll get proper crossfading. And here's how you do it. All right. Got a couple of elements. The from and the to. I mean, this is basically how you would do it today if you were doing it the hacky way that doesn't quite work. Yeah. It's the same. Layer the two on top of each other. That's your favorite trick, isn't it? All right. I had to put this in the slides. You don't have to do it this way, but I love this trick of using grid to put two elements on top of each other. I use this now most of the time instead of absolute positioning because the benefit is... You use grid. You use grid and you look cool in front of your friends. No. The container has layout. The container will take up the space of both elements combined. True because with absolute positioning you don't have an intrinsic size. You don't have a size on the layout size. That is actually a benefit. Yes. Absolutely. So I really like this. Anyway, back to the story. The two element, opacity zero. Again, nothing's unusual here. This is how you would do it even if you were doing it the slightly wrong way. Still waiting for the mind blowing? Well, mind blowing right there. There you go. This is the way it gets different. You apply this lighter mode. You only have to do it to the two element. Doesn't matter if you do it to both. But important thing you would need to do is isolate the container. And this is an existing property. This is not something you were proposing. This is something that's not already... I've never seen this in my life. So what it means is that for the compositing operation, stop at this element. So if you're using lighter, in the same way that if you use mix, burn, mode, multiply, it's not only going to do that compositing with the thing that is underneath it, it's going to be all the things that are underneath it. Also it's basically going to flatten the entire subtree first and then... In terms of pixels, not in terms of subtree is in a DOM tree, it's whatever pixels are behind it, it's going to blend with those. And with a crossfade, with this lighter mode, you only want it to be doing that operation with the other thing that you're fading. I've never seen it. It really only becomes relevant with mixed blend mode stuff, right? Or is there ever a use case for isolation outside of... No, it's just for mixed blend mode, I believe. Okay. So that means that, yeah, the crossfade container will... That will sort of be done in isolation. I guess. And then the result will be composited over composited with everything else, which gives you the result you're looking for. Yes. Okay. And that's it for the rest, just the usual stuff, like sort of unhover, but you can do whatever. I'm saying, yeah, so the from will fade to zero, to will fade to one. And you'll get a proper crossfade that looks like that, where just the pixels that need changing will change. And that's it. We're going to propose that to CSS working group. Hopefully they say yes. And hopefully we get this in browser soon. Because the implementations are already there, it's just exposing it via the keyboard. If you think about it, I'm kind of stunned that this actually isn't possible in CSS right now. So, same. Like, it's because, you know, if it's an image gallery or something, like crossfading items is something we actually do a lot. And we either rely on, yes, the want them being opaque items, or we do it wrong. So, let's start doing it right. That's all right. Right, I'm out. Where are you off? I'm leaving Google. You what? What am I going to do now? Action. So, so, so, so, so, so, so, so, so, so, so, so, so. So, so, so, so, so, so, so, so, so, so, so, so, so, so. I know, we had a couple of... No, I like to mute myself before I go to the urinal. Of course, of course. Yeah. We are on 203, there will be urinal stories. No, it's like, you know, I wouldn't blame Lucas for falling asleep having to listen to us babble on about text when he doesn't get good about it. Absolutely, absolutely.