Search

645: Mouthblogging CSS in 2024

Download MP3

Riffing off the CSS Wrapped 2024 list from the Chrome team, we're talking field-sizing, animate to height, anchor positioning, custom scrollbars, cross-document view transitions, scroll-driven animations, and more!

Tags:

Guests

Chris Coyier and Dave Rupert in silly sunglasses and a sign that says Shawp Tawlkk Shough DOT COM

Chris Coyier and Dave Rupert

This episode is with just Chris & Dave, ShopTalk Show's hosts. Chris is the co-founder of CodePen and creator of CSS-Tricks, and Dave is lead developer at Paravel.

Time Jump Links

Episode Sponsors 🧡

Transcript

[Banjo music]

MANTRA: Just Build Websites!

Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another episode of the ShopTalk Show. I'm Dave--in the shed--Rupert. With me is Chris--in the office--Coyier. Hey, Chris. How are you doing?

Chris Coyier: Fantastic. Thanks for having me, Dave. Um... Last week, we did an HTML edition.

Dave: Mm-hmm.

Chris: Because not every year can you do that, really. There's just not that much that changes in HTML year to year. There was enough to talk about and fill an episode for, and we did it. Then in between the time of recording that and this, Google (or the dev rels over there) put out CSS Wrapped 2024, which they've been doing year to year. I thought we could just do back to back episodes. We just did HTML. Let's do CSS now.

Dave: Let's do it!

Chris: This was actually Dave's idea.

Dave: Well... [Laughter] Dave's idea but Adam Argyle did all the work, I think.

Chris: Yeah.

Dave: The Chrome dev rel team here did all the work.

Chris: Yeah. It looks like it's Bramus and Rachel and Barry Pollard and Una Kravets.

Dave: Yeah.

Chris: They got the team at the bottom.

Dave: The whole squad? Okay. Yeah. But it's very... It's a very good site that really sort of shows everything that's come out, so it's really easy and digestible to be like, "Oh, yeah. This did happen."

Chris: Mm-hmm.

Dave: Pretty cool.

Chris: It's hosted on our favorite website in the world, too. Everybody should go to chrome.dev.

Dave: Yeah.

Chris: It's just an unordered list of links. [Laughter]

Dave: Yep.

Chris: The whole thing is, and clearly somebody over there handed them some power. They're like, "Here, y'all. If you need a website, here is your website. If you do a thing, just add it to the bottom of the list." Or the top in this case.

Dave: Yeah. I love... We're talking trillion-dollar company here - or whatever.

[Laughter]

Dave: And it's like a UL. It's good, chrome.dev.

Chris: No, it is good. I actually don't mind it because it's easy to find stuff.

Dave: Yeah.

Chris: Don't overthink it. Just make a list.

Dave: It's kind of like that CNN lite where that's better than the actual CNN.

Chris: Yeah. Yeah.

Dave: Where it's like, "Ooh, this is just better."

Chris: That's how I feel about text-based emails sometimes, too. When you need to say something to some people, you just say it with some words and send it rather than wrapping it in an HTML table and put a header graphic.

Dave: No, you get crazy, dude. Yeah, you know Unsplash? No Unsplash? You're just sending emails without Unsplash?

Chris: [Laughter]

Dave: Wow! Brave. Brave.

Chris: Well, it's a beautiful website in itself, of course. I'm sure they put in stuff. This site was begging for scroll-driven animations, so you can kind of see that going on as you scroll down, immediately.

Dave: And it has it. Yes, sir.

Chris: And the pixel font thing just screams Adam to me.

Dave: Mm-hmm.

Chris: You can just tell. I can tell his style.

Dave: It's a vibe. It's a vibe.

Chris: Without even looking at the get commits. You know?

Dave: Mm-hmm.

00:03:07

Chris: But what this does is it does the journalism for us here. We can kind of go down through the list and share some of the coolest stuff that's happened in CSS. It almost feels overused. I feel like I've written, "CSS has been popping off lately," some version of that I've written a few too many times at this point.

Dave: Mm-hmm.

Chris: I just feel like, "Yes, we all know that. CSS is going amazing." But they did a particularly good job here of showcasing some of this stuff, especially some of this stuff that you perhaps forgot about or that I have.

I'll read it and be like, "Oh, my God. Amazing!" Then it goes out of my head. In fact, I love their opener. The very first one is a CSS property called field-sizing.

Dave: Mm-hmm.

Chris: You can just chuck it on stuff like text area select and input. And it auto-sizes it then. Auto-sizes it like a text area where you could have it, say, be about three line-heights long. But as you keep typing, if you need more room, instead of a scrollbar being there and having it be this fixed size, it just grows as big as the text inside it is. It happens with one thing. You just say field sizing content, and it just does that job.

Dave: Isn't that wild? This is probably not super difficult, although measuring the text then to resize the thing is kind of a pain in the butt if you're trying to do this yourself. But now it's just one CSS property. Pretty cool.

Chris: It's actually a little bit difficult to do correctly.

Dave: Yeah?

00:04:42

Chris: My favorite one in the world, actually my coworker Stephen Shaw invented, that I thought was really cool. The idea was to make an invisible div that sits exactly above or below the actual text area that you're typing into.

Dave: Mm-hmm.

Chris: One line of JavaScript takes whatever the text in the text area is and propagates it to that invisible div. Then they're both set onto a CSS grid onto the same cell. You know what I mean?

Dave: Mm-hmm. Mm-hmm.

Chris: That technique where you say grid-area: 1 / 1 - or whatever - for both of them.

Dave: Yeah.

Chris: So, they're sitting on top of each other exactly. Then if either one of them naturally grows in height, the other one will grow with it because they're part of the same cell. You can't actually see that div with the text in it. It's invisible. But as the text is propagated to it, it's growing in height naturally (based on the text that's inside) and it's pulling the text area larger with it.

Dave: Yeah. Yeah.

Chris: It's just a one-liner of JavaScript and a little tricky CSS and you get this effect. Put it requires a little JavaScript, yadda-yadda-yadda. This is one line of CSS! Field sizing content. Done. Ship it.

Dave: Done. Yeah. No, that's pretty revolutionary. We have a bunch of field sizing coded in our codebase, and I'm like, "Ew... When do I rip this out?" [Laughter] You know?

Chris: Yeah.

Dave: How quick can I rip this out?

Chris: Works for any font, any size, any language, any writing mode, anything-anything. That's why you want the browser platform to do stuff for you is because of that.

Dave: Yeah.

Chris: You just get all this stuff (that you didn't even think about) for free then.

Dave: Mm-hmm.

Chris: All those "what ifs," they dealt with that, the edge cases that you didn't think about, which is really cool. I really mostly like it for text areas. I think it's a little funky that it works in line direction, too. I'm glad that it does. That's cool. That seems a little more gimmicky or something.

Dave: Um... Yeah.

Chris: I'm less into it there.

Dave: Yeah. That's kind of maybe not as useful. It's always weird that selects kind of did it by default, too, like a select gets wider.

Chris: Yeah.

Dave: If you don't set a width.

Chris: They kind of already did that?

00:07:00

Dave: Yeah. Yeah. Well, the next one, Christopher, I feel like you (through 1,000 blog posts, approximately, on this topic) animating to height auto, is now something you can do.

Chris: I probably have written on and off about this for a decade, at least.

Dave: Yeah. For sure. For sure.

Chris: And commissioned articles on and stuff because people have been solving this for forever. I remember old-school techniques where you'd be like, okay... Like in jQuery or something. I have an element and I know that I need to animate it to an arbitrary size that I don't know what it is yet because some content is going to arrive in it that I don't know what the sizes of it is. So, there'd be tricks like, okay, well, as soon as you get the content then make a div off the screen, like off to the left where it won't cause a scroll bar. Then render it there. Then measure that with JavaScript. That way you'll have a pixel value. Then you can animate from the existing pixel value to that new pixel value that you measured off-screen - or something. [Laughter] You're like, "Okay. Seems like a lot, but I guess."

Dave: Mm-hmm. Yeah.

Chris: That was just one variation of it. People have been solving this, like, "How do you animate to an unknown new height?" or if you don't know what the height of something is because you don't in CSS. Like, how tall is a div in CSS? You have no idea.

Dave: Um... 400 pixels.

Chris: Yeah, right. [Laughter] You just can't ask. That's not how the CSS language works.

Dave: Right. Right.

Chris: Since you don't know what it is in CSS but you want it to animate back down to zero, that's not possible either, too. You generally want height in CSS to not be set. Generally, you want things to just flow. You want them to be as tall as they need to be. But then it's very reasonable that you'd want to then animate it back down to zero because you're animating it off the screen or you're collapsing something - or whatever.

Dave: Mm-hmm.

Chris: And it was impossible to animate anything from zero up to its auto height or the reverse, from its auto height back down to zero.

Another trick was just to animate the max and the min. That never felt good either because it was always the wrong height, so you'd be animating this maximum and part of that transition would be through some pixels that were useless. Anyway, that was a lot of how it used to be.

Dave: It would yo-yo, and it never felt right.

Chris: Right.

Dave: Yeah.

00:09:30

Chris: They kind of solved it again in a pretty neat way. The part that's not so neat is like, what do these words mean? Interpolate size colon allow keywords.

In this case, I think what they're saying with allow keywords is auto. Auto is one of those keywords. Auto is just one of them. It also means that it's not just allowing auto. It's allowing whatever: mid content or fit content or these other keywords. They don't say a size. They just represent a size, essentially.

Dave: Mm-hmm.

Chris: You can animate to those, too, which is pretty cool. This is an opt-in. The reason it's an opt-in is because there's probably code that is trying to animate to auto that currently isn't working. And if all of a sudden it did start working you'd think that'd be good, right? It's not. It's actually bad because you can have a website that, all of a sudden, has drastically different behavior just because something changed on the Web platform. Instead, they have to say, "If you want this behavior, you're going to need to opt into it."

We talked about this last week with selects, the new styleable select needs an opt-in. That opt-in is happening in CSS. This opt-in is happening in CSS as well. It makes a little more sense here because it's a CSS thing that you're opting into in CSS.

Dave: Yeah.

Chris: But then it does the trick, man. Animate to auto. I can't believe it here. To me, this seemed even more unlikely somehow than container queries.

Dave: Mm-hmm.

Chris: But here we are. We've got it now.

Dave: Well, and we're going to maybe talk--

Chris: No Chrome, no Safari, though. I mean no Safari, no Firefox.

Dave: No Firefox. Yeah. Then there's also... In this article, which I hadn't really seen, they're kind of suggesting putting it on the root, like :root interpolate size.

Chris: Yeah, opting the whole page is what that's saying, too. You don't have to, though.

Dave: Yeah.

Chris: You can opt-in at any point in the DOM tree if you'd like to.

Dave: Then they were also saying there's this calc size function, which is kind of like you can basically tell it to choose between sizes, basically, or max-content size. Yeah.

Chris: It's a different opt-in is what it is. It's like a way instead of changing the interpolation behavior - or whatever - at all. You don't have to use it at all in the document. You can still make it work. You just need to set the transition when you're setting the thing that you're trying to transition, like the height or the width - or whatever it is.

Dave: Like width calc height.

Chris: You have to do it through calc size.

Dave: Yeah.

Chris: Yeah, which I kind of like.

Dave: Then there are some keywords that are stuffed in there.

00:12:08

Chris: I think calc size is easier to sprinkle in and feels safer about.

Dave: Mm-hmm. Mm-hmm.

Chris: Rather than setting interpolate size at some really high level.

Dave: Yeah. I would imagine if you have a bunch of divs that sort of change size or if you're flying in and you're doing bad with animations and not using transition, using padding or something, it might go kind of haywire. I could imagine situations where you have too many DOM nodes and this becomes a performance bottleneck maybe. But I don't know. I'd be curious.

Chris: Yeah. Yep, hard to say. There's no real performance information in here. It tends to be (when stuff like this drops) what they're implicitly saying is, "Don't worry about it."

Dave: Yeah. Yeah, they don't put it in there unless it can do 60 FPS.

Chris: Yeah, right.

Dave: Cool.

00:13:00

Chris: It looks like an HTML one next. Let's skip that. We already talked about it last week. We talked about all of it.

Dave: Yeah. Exclusive details and styleable details. You get the details content. Yeah.

Chris: Yeah.

Dave: That's a big one.

Chris: It's neat. Good job. Thanks, everybody. [Laughter]

Dave: Yeah.

Chris: The next really CSS one on here is anchor positioning. It's in the same boat, though. No Firefox, no Safari. Those things do make me wonder a little bit. Neither of those things, certainly, are an interop because they're just too new.

Dave: Mm-hmm.

Chris: But I think, by the time the next interop rolls around, these things will be very hot (if they're not already done). But anchor positioning is just huge. Another one of these things that just... As somebody that's been kind of covering CSS for as long as I have, oh, my God, is it wild that this exists. And I think this will be very... I don't know about very, but pretty easy to teach. I think when you're showing somebody how layout works in CSS, if you tell them, "Oh, there is this technique where you can tell an element to be where another element already is. One is called an anchor and then you position against that anchor," that just seems so logical. Of course, you can do that.

It's also true that you can do that in other layout languages, as far as I know. I'm not super-versed on how Swift UI works and stuff. But I'm told that that kind of thing is pretty obvious and able to be done. If you're programming a game or something, can you imagine not having that ability, not having my character who is walking around on the screen, and I open up a menu for what they're carrying in their backpack, that better as hell be anchored to them. You know?

Dave: Yeah.

Chris: So, that type of stuff is obvious, and now that has arrived in CSS as well.

I hesitated to say that it's super easy just because there is some tricky stuff to think about: how you name them, how that name propagates and stuff, and then all that try stuff is pretty funky. Not in a bad way, but you need to know, hey, if I have said I want you to answer this thing above this element, well, neat. Great. Good for you. But what do you want to happen when there's not room above that element anymore because it's already butted up against the screen? Would you like it to then be below that element instead? Well, if you do, which you probably do, you need to code that yourself. That's just a smidge cumbersome, I'd say.

Dave: Yeah. It's sort of like I think it has a really good set of defaults. And if you want to go wild, you can, I guess. Yeah.

Chris: Yeah. It's just an amazing addition to CSS. I don't know. What do people think about that? How do you think about the idea that, like, "Oh, look. It's just absolutely not in Safari. It's not even in--" I don't even know if there's a flag. Does that turn your brain off to the whole thing?

00:16:11

Dave: We're using it, so it's shipping.

Chris: Oh, wow.

Dave: Ta-da! But there's an OddBird, Miriam, a friend of the show.

Chris: Polyfill is what you're saying?

Dave: Polyfill from OddBird out there.

Chris: Okay.

Dave: It doesn't have 100% feature set coverage but it is pretty good. There's a little trick with Shadow DOM. I won't bore people too much. But you have to have the styles mounted and then run the plugin (if that makes sense) because it parses every element in the thing.

We made a patch to it to where you can just run it on a single element, so that's what we do. We just say run it on our element we just put in there, please.

Chris: I see.

Dave: If necessary if not supported.

Chris: Yeah.

Dave: We chuck it in there if needed. Sorry, my brain is going a million miles. There's also a weird deal with Shadow DOM, and this is not... If you're using adopted style sheets, which you kind of want to with Web components, basically.

Chris: Right.

Dave: Which is just this idea of, like, you don't actually do link rel my component dot CSS. You don't do that. You just basically push it into the ShadowRoot's list of style sheets, the array of style sheets that the document--

Chris: How do you get the reference to it?

Dave: Well, it auto-maps to that ShadowRoot. But you can actually do document dot adopted style sheets or ShadowRoot... my element dot ShadowRoot dot adopted style sheets and get a list of the style sheets.

Chris: Hmm...

Dave: Or maybe it's dot CSS style sheets - or something like that. Anyway, it's in there.

Chris: Oh, I see. So, the parent page already has some style sheets sitting there available to grab.

Dave: Yeah! Yeah.

Chris: But you're using Shadow DOM, which won't have those style sheets available. But you're saying you can use Shadow DOM but, on the parent, you can just be like, "Well, just mount the ones that are already there then.

Dave: Yeah, you could. You totally could. But the twist is, with polyfills -- and this just a Shadow DOM thing I learned this year -- if you say position anchor and I'm putting that in the style sheet and one thing that polyfills do is they will... Sorry, adopted style sheets will do, it'll just kick out. It'll reject any style it doesn't understand. Uh-oh! We have a problem. You actually have to write a style block to the element's Shadow DOM to get it to work. A little twist. Or to the parent.

Chris: Yeah.

Dave: Then you have to... Yeah. Anyway, it's a little twist, but yeah. Then anchors don't work in ShadowRoots. That's kind of a thing, so you have to apply it to the host element itself, and so that's a little frustrating, but it makes sense in spec land. Yeah, there are some gotchas.

00:19:19

Chris: I had one the other day, and I was using Lit again. I should try FAST. Does FAST have a CSS? Let's say you need three lines of CSS. Is there a little helper method to do that? I'm sure there is of some kind.

Dave: Yeah. Well, yeah. We have CSS. But in a Lit component, you kind of all write it inline, right? You say class my element extends LitElement.

Chris: Yep.

Dave: Then you do whatever, get styles, and then you do render, and your template and your styles kind of live inside of there.

Chris: Mm-hmm.

Dave: FAST, it's completely decoupled. And so, you write a style block. You write an HTML block or a template block. Then you compose the element. What's neat about that is you can actually compose multiple style sheets.

Chris: Like as a build step?

Dave: Well, it's like a pre-- It creates the class with these things. You are basically adding these things to the FAST Element instance. Then FAST Element knows what to do with it. But what's cool about it is styles can be an array, so you can actually pass my styles for whatever weird stuff I'm doing and bootstrap CSS if you wanted to. You can adopt the whole bootstrap CSS if you wanted to.

Chris: Yeah.

Dave: It's pretty rare, but it's something you can do, so it's weird. Yeah.

Chris: Yeah. It looks like, in Lit, you just go static styles equals, and then CSS has a tag to template literal. Then whatever is in there, just however that works, it's just their little API.

Dave: FAST works the same, but you just do const styles equals CSS backtick.

Chris: Oh, I see. Yeah, that's neat. But what I found, though, is it only applies to the CSS that gets rendered by that component.

Dave: Mm-hmm.

Chris: Which I guess that sounds obvious to say, but if you have some Light DOM that you're just letting get rendered in there, too, because you're just going to rock the Light DOM, that CSS just totally doesn't apply at all to it. Then you're like, "Well, that's half an API then." [Laughter]

Dave: Yeah. Well, you can use ::slotted() in target elements that gets slotted in. But the limitation there is you can only do one depth, one nested, like one deep, basically root plus one.

Chris: Root plus one.

Dave: If you had a header H1 in there, you couldn't get the H1. But if you--

Chris: I'd had a whole block of styles. I was like, "Where do I put these then if I want to ship them with this Web component?" I'm back to, like, "I guess it's just a style block in the render method."

Dave: Yeah.

Chris: Which is like, "Okay."

Dave: Yeah, you could do style block there. You could also chuck it up, like, put it on the parent. Or do this adopted style sheet thing. You could do, like, my element header H1 background purple - or whatever you wanted.

Chris: Yep. Yep, that's what I did. I was like, "Well, it's Light DOM anyway," and kind of the point, in my opinion, one of the reasons you'd go Light DOM is because you just want a style on the parent page anyway.

Dave: Mm-hmm. Mm-hmm.

Chris: That's what I'm trying to do.

Dave: Yeah.

Chris: So, I just did that. It ended up being a mixture though. I thought it was kind of interesting. It was a little--

Imagine a photo slider or something. You want the Light DOM to be the five images, say. And so, if JavaScript doesn't load or whatever, you ship it in a blog post where it will never run, you see the five images. Boom-boom-boom-boom-boom. But then if it does run, you want to add all that dynamic crap later.

Dave: Mm-hmm.

Chris: Meaning some of it is Light DOM and some of it is rendered by the Web component, like the little back and forward buttons - or something. You wouldn't put that in the Light DOM--

Dave: No. Yeah.

Chris: --because you might as well add those when you mount it.

Dave: Yeah.

00:23:33

Chris: I was like, is this Shadow DOM or is this Light DOM? Actually, that was the wrong question because it really still could be either.

Dave: Yeah. It's up to you. That's the weird part. That's my whole deal with Web components and their SSR ability. It's really how much do you want to do. You could actually put the previous next buttons in the Light DOM if you felt super good about that.

Chris: Yeah... Why would that ever feel good?

Dave: Exactly. Yeah. Don't do it.

Chris: Yeah. [Laughter]

Dave: Yeah. [Laughter] I think it's new enough. Even me, I'm like, where does this go? It adds a little bit of decision-making, which I know developers hate to make decisions but it adds a little bit of decision-making. But it also creates flexibility. I think that's how I'd spin it.

Chris: Yeah. It was okay in the end. It was kind of confusing. Then it's weird to ship the CSS API that's--

Dave: Three lines. Yeah.

Chris: "If you render it this way, it doesn't work." Why? Why? That's weird.

Dave: Yeah. Yeah, yeah. Nah, I mean that's kind of... I don't know. You have to think about that, though, kind of.

Chris: Yeah.

Dave: It's not going to work in an RSS feed or something like that. You have to kind of come up with--

Chris: Yeah, exactly. That was my top thought is that these things deserve to be wherever content can be and sometimes content gets syndicated or crawled or whatever. Yeah.

Anyway, let's move on. We just can't help ourselves.

Dave: No.

Chris: It's absolutely the Web component show.

Dave: Sorry. Web component. We talked about Web components. I'll donate $5 to a charity.

[Laughter]

00:25:14

[Banjo music starts]

Chris: You've got ideas. Now all you need is a website to make them real. Good news. Bluehost makes that super-easy. It's the all-in-one platform for building and hosting websites.

You can save time on design and use AI to build a custom WordPress site within minutes, so no coding skills needed, just your ideas. Bluehost also has tools to help you optimize and scale your website's growth all in one place. Things like blogging, SEO, social posting, email campaigns, and so much more.

Then when you upgrade to Bluehost Cloud, you can start managing multiple sites and domains. Not only that, you get 100% uptime, enhanced security, and priority 24/7 support to help keep you online no matter what. That means no crashing from heavy traffic.

Start seizing your dreams today. Build your brand. Build your following. Build your website. Build it with Bluehost. Now that is a great idea. Go to bluehost.com/shoptalk to start building your dream website today.

[Banjo music stops]

00:26:22

Dave: Hey, so they broke it up. That was components. We're getting into the interaction section. Custom scrollbars is now a thing. That's another Chris Coyier--

Chris: It feels like a step backwards in a way. Yeah.

Dave: Are we--? This is like they took all the CSS-Tricks articles from, like, 2014 and just started doing them.

[Laughter]

Chris: Yeah. Just started to make young Chris happy.

Dave: It's Chris's wish list. Yeah. So, we have covered styling.

Chris: This one is funny because if you use the dash WebKit scrollbar, you have a ridiculous amount of control over the scrollbar.

Dave: Mm-hmm.

Chris: I think the standards bodies that be long ago where like, "Yeah, maybe not." The stuff that we're going to standardize is we're going to let you set some colors and give you three keywords about how wide it can be.

Dave: Mm-hmm.

Chris: That is literally all you can do with the standardized scrollbar things. I don't hate it necessarily. I think sometimes taking the baby step first is okay. I especially like it because you can use transparent, for example, on the track. If you want to not see it and stuff, you can do things like that. I don't mind it. It is a little tricky that it doesn't even say so here, but I've played with this, so I happen to know is that you can't do both.

Dave: Mm-hmm. Mm-hmm.

Chris: As soon as you have one of these standard ones applied, it turns off the fancier ones.

Dave: Oh, really?

Chris: So, you kind of have to decide, how fancy were my old ones? Do I really need those to still be there? If you are, you might be in one of those really awkward situations where you're trying to guess if you're in Firefox or not.

Dave: Mm-hmm. Mm-hmm.

Chris: I have tried to be like, if you are going to style scrollbars, you probably should just use these two (scrollbar color and scrollbar width) and just forget everything else. That's what the world wants you to do, so you should do that.

Dave: Yeah. Is scrollbar width working? Maybe I'm... I'm trying to set it to something--

Chris: The last I checked, it was just keywords. It's thin, normal. I think thin is the only one that's really relevant. It's the normal size or slightly smaller.

Dave: Oh, okay.

Chris: Can't go bigger.

Dave: Oh, I wanted to set it to like 200 pixs. [Laughter]

Chris: That's not happening. Yeah, you can't do that.

Dave: They don't let me do that? Okay. Well--

Chris: Nope. It's a shame.

Dave: All right.

Chris: I always liked the chonky ones. I almost made an argument one time that I think that increases accessibility because I like using my mouse. I occasionally mouse over to the scrollbar, grab that thing, and drag it around on a webpage. I'm a person, too.

Dave: Yeah.

Chris: And I like it when that target is a big, beefy 50 pixels, let's say.

Dave: Yeah.

Chris: Instead of the 13 or whatever it is.

Dave: As somebody who uses a trackpad, I certainly agree. Yeah, it's so useful to just have as much handle as I can get without killing the design.

00:29:22

Chris: Yeah. The next one is cross-document view transitions. I don't know why they split it out. I don't mind that they do because they do feel like pretty different APIs to me.

Dave: Mm-hmm.

Chris: There's one that it's just a JavaScript thing and you call it and then things get translated. And the other one is you click a link and go to a different webpage. There's a lot different about those two things. I get that they share some things.

Dave: Mm-hmm.

Chris: I don't mind that they get talked about individually because it seems to make more sense. The cross-document one requires no JavaScript at all. In fact, JavaScript isn't even particularly relevant to them.

The idea is that, as you click a link, on the next page that it looks at it finds things with the same view transition name and transitions them from the old page to the new page. It really can look truly amazing that that is even possible.

Dave: Mm-hmm.

Chris: You have to opt into it, of course, so there's that thing going on. You have to get the view transition names right. You can control it all in CSS but it does tend to just work.

That just recently dropped in Safari, so now Firefox is the only one not supporting that. It's pretty progressive enhancement, though. So, kind of who cares if Firefox doesn't support. They just move to the next page. Not a huge deal.

Dave: You just get a normal page load.

Chris: Yeah.

Dave: Then you get a spicy one if you add one line of CSS. I love it.

Chris: Yeah.

Dave: We should do it more.

Chris: I was soured on this a little bit at one point this year. Do you remember that where I had to put a pretty simple demo of it together? To get it to work, it was happening about 50% of the time it worked. I was like, "What's up with that?"

I talked to some people involved, and they were like, "No, that's about right if you just leave the page performance its normal style." It tries to really quickly do one render of the next page. If your view transition name is there, then it'll do it. But if it's not in that really quick first render, it just bails out on doing the view transition at all.

Now the way to make sure that your view transition works (if you really like it) is to essentially put blocking behavior in on that particular element or just block the whole page and be like, "Well, just don't even--" Just block the whole page and then your view transition will run for sure because it's rendered the whole page before it moves.

That's harming the performance of the next page. You're saying my transition is more important than loading the next page. Maybe it is for you. No shame.

Dave: Mm-hmm.

Chris: But I was a little bummed out. This isn't just all super-duper positive all the time.

Dave: Yeah. Yeah.

Chris: I can see developers being like, "Ooh, I'm mad that my view transitions aren't working all the time, so I'm going to intentionally put blocking crap into my website to stop that." Blah!

Dave: Yeah.

Chris: Not my favorite.

Dave: I understand the desire. I am way too A) lazy but then B) just like, "Man, we've got to--" Blocking the user is old Flash stuff. We probably shouldn't do that. But I'm glad it exists if you need the fidelity in your animation.

Chris: Yeah.

Dave: But I just don't think--

Chris: We do make choices like that sometimes. Font rendering is the biggest example I tend to think of where you can now control in CSS what you want that behavior to be like. One of the settings you can set is don't even render the font -- the custom font, that is -- until it's ready to go so that you're not seeing what is traditionally called the flash of unstyled text.

Dave: What is it called? Swap is a good one. But wait?

Chris: I don't know. I hesitate.

Dave: Wait forever? [Laughter]

Chris: Yeah. It's font swap. Swap or something.

Dave: Font... Yeah.

Chris: People point to swap as being the good one because it's the one that's the most never block my content ever. Make sure that it is displayed instantaneously. I guess that's just the circles we run in. I would not doubt that there are other circles that don't like value because they want the page to not flash between two different fonts in reflow.

Dave: Yeah.

Chris: That's a weird performance thing.

Dave: Probably my coworkers.

Chris: It's a UX thing. It's an aesthetic thing.

Dave: Yeah.

Chris: Yeah.

[Laughter]

Dave: To be fair, probably my coworkers.

Chris: Yeah. I hate to admit I'm kind of in that category. If I knew somebody was on a slow Internet connection, a low-powered device, or whatever, of course I'm not trying to block them. But I wish there was a better way to know that.

Dave: Mm-hmm.

Chris: Because I think if you're on a decent device, the penalty for seeing reflowed content and font swap is pretty gross.

00:34:10

Dave: Yeah. There's also the optional one, font display or optional, where it's like I'll load it. I'll load the font, but I'm not showing it this time. Maybe the next time.

Chris: I like that one.

Dave: That one is kind of chill.

Chris: I think that's the most hated one, and I think it's my favorite one.

Dave: Yeah. Yeah, it's kind of like--

Chris: Don't flop it out this time but put it in your cache. That way it will be fast next time.

Dave: Yeah.

Chris: Then, next page load, you'll see it.

Dave: Yeah.

Chris: I don't know why that's so hated. I kind of love that.

Dave: You know you've got to... People are picky. Yeah.

Chris: Yeah.

Dave: People want it to look right. Hell hath no fury like a typographer scorned.

Chris: [Laughter]

Dave: I've worked with enough typographers that they will notice, Chris, 100%. [Laughter]

Chris: Yeah.

Dave: They stare at--

Chris: I remember feeling bad for Paul Irish, and I think he possibly coined FOUT.

Dave: Oh, yeah.

Chris: Then he was at Chrome. This is ages ago. I think he still is, probably. But then was like, "Oh, gawd. We're so sorry about FOUT. We'll ship some way to stop it." I think something then got out of some way to stop FOUT. Then people were like, "Wait! But that's bad for performance." Then this thing that he worked hard to fix was actually then demonized.

Dave: Yeah!

Chris: You're like, okay. What do you all want?! Gees!

Dave: There's that Web font loading API. That's kind of ancient tech, right? But I'm sure some people still use it for Typekits and all this stuff.

Chris: Mm-hmm.

Dave: Oh, those are the days. Stuff I probably--

Chris: That's what I mean by people intentionally putting blocking stuff in, though.

Dave: Mm-hmm.

Chris: You can use that to literally just... All you could do is say, "Oh, when these fonts are loaded then set a class of ready on your document, and ready goes from display none to display block."

Dave: Yeah.

Chris: People do that.

00:36:20

Dave: Yeah. I mean we should take a minute to honor how far we've come. We're arguing about, "Oh, it's going to show up 300 milliseconds late. Oh, my God! That's insufferable."

Chris: Yeah.

Dave: Where the old days, we'd be loading a five megabyte TTF file inside a Flash movie to--

[Laughter]

Chris: Yeah.

Dave: --put a damn font on a heading.

Chris: Mm-hmm.

Dave: We did very bad, and you'd get, "Update Adobe Flash," inside your heading, so it just wasn't good, man. We didn't do a good job. This is great tech.

Chris: Yeah.

Dave: We're really arguing about--

Chris: Yeah, you don't realize. It's been a while since we've talked about all the typographic improvements that happen on the Web. That was more like, I don't know, half a decade ago. But that stuff was pretty big for the Web.

Dave: I'll give a shout out to Richard Rutter, clagnut, over in the UK has a really awesome introducing TODS, a typographic and open default stylesheet.

Chris: Mm-hmm. I saw this the other day.

Dave: It's basically a typographic-driven CSS reset that rules. And so, I'm just going to shout it out, put it in the old show notes.

Chris: The old TODS. Isn't it full of a bunch of utility classes, too, for fancy--

Dave: Yeah.

Chris: --the fancy stuff you can do? Like, "Do you need lining numbers? Then just use the class LTND," or whatever.

Dave: Yeah. He has all these things. If you want that F that looks like an S - or whatever - the S that looks like an F--

Chris: An alternate character?

Dave: Alternate characters on just your H1, you can get that. You know what I mean? You can get these kerning pairs and stuff like that. I think he has those kind of classes for that.

Chris: Yeah. Yeah. I mean notably you need to be using a font that has that, which precious few do. The ones that do are big.

Dave: Mm-hmm. Yeah.

Chris: So, it is kind of like yes all this stuff is technically possible but it's not possible in - whatever - Helvetica.

00:38:30

Dave: Yeah. I just think my favorite part about this post, which it's good reading, but it's just A) how far has type come. All this stuff we can control is outrageous.

Chris: Mm-hmm.

Dave: But then B) I love that he's basically written a CSS reset and then commented the whole thing out completely. That is beautiful to me.

Chris: Yeah, it's a really classic kind of old-school, like the HTML 5 boilerplate kind of thing.

Dave: Yeah, it's great.

00:39:07

Chris: Yeah. I saw open type tends to be this stuff. There's a lot of open type features in it.

Dave: Mm-hmm. Mm-hmm.

Chris: When you declare... I remember when I first saw it, there was an interesting... It does have that reset like quality. "Do this stuff because--" It's stuff that you'll forget to do. One of them was, when you're using a font like that, to set the font weight property, which is different. Are you aware of this? I'm sure you are.

When you're inside of an @fontface block in CSS, the properties inside of that that you're setting are real weird.

Dave: Mm-hmm.

Chris: When you're in a font face block and you set font weight bold, you're not saying when I use this font I want it to be bold. You're not setting bold type anywhere on the page itself. You're saying that this font face applies only to bold test.

Dave: Yeah.

Chris: It's really twisty to think about.

Dave: Yeah.

Chris: Yeah. [Laughter]

Dave: It's different, huh?

Chris: It's different. They even have a different word. I can't remember the terminology.

Dave: I think it's font weight, but it's like--

Chris: It's font weight in there, and he says, "Use the value 1 1000." What you're doing there is making sure that you have the full weight possibility of the font because those are the theoretical minimums and maximums.

Dave: Oh, yeah. Yeah.

Chris: If you don't do that, you might be limiting, for example, how bold a font can get, even if it can get bolder.

Dave: Oh, man.

Chris: I was like, "What a foot gun is that?" Thank you.

Dave: What a foot gun. I agree. I would have messed it up. I probably have messed it up in multiple places because I think I'm just like, "Oh, font weight normal. That sounds good. I did it."

Chris: Yeah.

Dave: That's how I have my brain programmed.

00:40:56

Chris: Cool. Scroll driven animations, I guess is on here, another one that's just absolutely massive.

Dave: Yep.

Chris: It's more of just like fun in a way. [Laughter] You know?

Dave: It's a little spice, right? It's a little spice for your webpage, right?

Chris: Yeah. The bigger... There's the obvious one is in here, which is how far scrolled down are you. Is it 80%? Cool. I'll make this keyframe animation at 80% through the keyframe animation.

Dave: Mm-hmm.

Chris: To me that's very easy and obvious to understand and apply. Cool. Good.

It's also less useful. There's another kind of scroll driven animation that you apply to a particular element.

Dave: Mm-hmm.

Chris: Then what it's saying is when it enters the viewport, then start the keyframe animations on it and run it one through 100% as its journey through the viewport continues and then goes away. But it's even that not that simple because you're like, "Well, how in the viewport then? If it's one pixel in the viewport, do you want to start the thing? Or do you want to start it when it's 50% in the viewport? Or does it need to be 100% in the viewport?" All that stuff is setable, so there's just a lot of control there that makes it kind of a little more extra complicated.

Then there's this other one more complication I'll go through on it is that when you're setting this thing, what's the element that's scrolling? There's some element, and it can scroll zero to 100%, whatever element that is anywhere on the page. It could be the scrolling element itself, the document. But it also can be just any old div or something like that. You can just say, "Oh, name that scroll timeline. Just name it. Name it Dave's scroll timeline."

Dave: Mm-hmm.

Chris: You don't have to do anything with it. You can just name it. Now it has a name. Then any other element, a child (although, you can, on purpose, propagate it up higher). I got that wrong on a podcast a little while back, too.

Dave: Oh...

Chris: I was like, "You can only do it on children," which is not true. You can push it up if you want to.

Dave: Oh, really? You got in trouble without me? That's great.

Chris: [Laughter] Yeah.

Dave: That's a first. Usually, it's me. [Laughter]

Chris: [Laughter] Yeah. So, any element, you can use the scroll timeline of any other element. Isn't that a mind blaster?

Dave: That is a mind blaster.

Chris: Yeah. You can be like, "Just listen to Dave's timeline over here," some random div scrolling downwards, but have this element somewhere totally else on the page be reacting to it.

Dave: Yeah.

Chris: It's a little hard... It's just like, "What? Wow!"

Dave: It's pretty wild.

Chris: Almost it's interesting that it's possible. My mind doesn't admittedly flood with ideas for that kind of thing. But it was kind of there.

I was thinking of making a game. Like there are ten divs all over the page and you've got to scroll them all to just the right position to unlock a lock or something.

Dave: Yeah.

Chris: I don't know. That kind of thing.

Dave: Yeah, yeah. Well, no. I was just going to say a little easter egg.

Chris: Yeah?

Dave: They're actually using scroll driven animations to highlight the scroll spy nav in this website. They're doing a little... As divs are showing up on the page, they're highlighting scrolling, how much--

Chris: Oh, in the hamburger menu sidebar thingy.

Dave: Yeah, in the sidebar.

Chris: Oh, my God. That is really nice.

Dave: A pretty cool trick. If you just wanted to see a power, that's one... That's a static element reacting to another element scrolling or another element scrolling into view.

Chris: It is, yeah. These aren't necessarily children or anything.

Dave: Yeah, that's going to be the example. Yeah.

00:44:36

Chris: It looks like... Usually, when I see this, what's actually happening is that there's a pseudo element or something and then it's scale Y value is a value from zero to 100, like a custom property that they animate, which means that the custom property needs to have @property on it so that CSS knows what it is.

Dave: Mm-hmm.

Chris: Then you animate that custom property from zero to 100%, and the scale X squishes it.

Dave: Yeah.

Chris: Clever, clever.

Dave: Well, and they're even auto-opening divs and stuff that I'm curious how they're doing that. That seems like impossible, but maybe they're doing the display stuff. I don't know. Interesting.

I'm running out of time, but we should keep going. [Laughter]

00:45:23

Dave: The next section they get into is developer experience, like little fixes, I guess you might say. [Laughter]

Chris: Hmm...

Chris: I don't know. There's actually some big stuff, but something like fixes just like, "Oh, yeah. That was always a pain in the butt." Backdrop will now inherit styles. You used to have to redeclare variables on ::backdrop, so that was--

Chris: Weird. I didn't know that.

Dave: Yeah, I don't think I ever noticed it either. [Laughter] But now you don't, so that's great.

Chris: All I've ever done with backdrop is, like, black or--

Dave: Yeah.

Chris: --make it a cool gradient - or something.

Dave: Yeah.

Chris: Yeah.

Dave: Yeah, exactly. But it's like blur 2 pixs, something like that, but so anyway that's easy. Light-dark, I'm actually super-hyped about this one. I'm not allowed to use it at work. [Laughter]

Chris: I used it just the other day.

Dave: I love it.

Chris: I think this is a hit. I think it's okay.

Dave: Mm-hmm.

Chris: It's not my favorite thing because I almost prefer to just change what the custom property is and then use that custom property.

Dave: Mm-hmm. Mm-hmm.

Chris: I'm less hyped on this. But I'm stoked about how stoked other people are about it. I think people really get it. They're like, "Oh, yeah. Use this value when it's light and this value when it's dark. I can do that all in one declaration. Cool." Good.

Dave: I have light-dark themes on my site, and I even have a theme.dark or root.dark or something like that.

Chris: Yeah.

Dave: I don't need that. I can just say if I want this post to be dark, I just say whatever, body color scheme dark, and it should go to the dark theme.

Chris: Yeah.

Dave: You know what I mean? It seems--

00:47:06

Chris: That is a tricky thing because you know there's a media query, @media prefers color scheme light or dark.

Dave: Yeah.

Chris: You can do that and it will respond to your color scheme no matter what. But there is this other property that is often shown on the root (one of those things) called color scheme. And in order for the light-dark function to really do anything... You don't have to set them both. You can. Then it'll work. But if you, for example, set color scheme light, the light-dark function will only ever resolve to the light value.

Dave: Mm-hmm.

Chris: You know what I mean? Generally, you set them both so that it can go back and forth between those two values or your dynamically changing the color scheme value with JavaScript as you need to on the page. It's just a little bit of a mind-meld-y weird thing that I don't--

Dave: Yeah.

Chris: It took me a minute to kind of understand in a way. It's like color scheme is very powerful and it almost scares me a little bit. [Laughter]

Dave: Yeah. Yeah. Yeah, color schemes and it's not the best in Safari by default. If you're like, "This is my whole strategy for light-dark," it's not super great in Safari. Hopefully, that gets fixed.

Chris: Hmm... Okay.

Dave: It's blue on black, like hyperlink blue on black. It doesn't work. [Laughter]

Chris: Yeah.

Dave: Hopefully, it gets improved.

Chris: Another thing that you buy when you do... This unlocks the real color scheme dark - or whatever - instead of you setting some colors based on the user preference. If you set color scheme dark and the user is in dark, that means you buy all this other stuff for free.

Dave: Mm-hmm.

Chris: You buy the canvas color, for example, changes. Your radio buttons go dark. Your scrollbars go dark. It feels more authentic real dark mode.

Dave: Yeah.

Chris: Where you have to do less work.

Dave: I think it's worth, if I can just - whatever - exert people in the right direction - not extort. I think there's going to be this whole schemed color thing. If you wanted to drop in a Sepia theme or something like that, like your own themes, I think this is how. It's going to come through an API like this. So, if you get used to using this, you should have no trouble adopting this whole idea of bespoke color schemes kind of deal.

Chris: Yeah.

Dave: Kind of exciting.

00:49:26

Chris: We'll just do this one last one because I know you've got to get out of here. There's this new @ rule called @starting-style that's amazing that's just waiting on Firefox on that one. It's in both Chrome and Safari. Pretty cool.

[Laughter] The example here is one of my favorites because it's a CSS-Tricks article from 2012 is how to do the yellow flash, which is when an element is added to the page.

Dave: [Laughter] Yeah.

Chris: When you jump down to it, it flashes yellow real quick just to draw your eye to it, like, "Hey, this is new!" You could always do that with a keyframe animation. You could just apply an animation to it with a fill mode forwards or something that flash to yellow then back to white - whatever. Then when it gets applied to the page, that animation will run that one time and you'll see it.

You don't have to do that anymore. It felt a little weird to have to use a keyframe animation for that. Now you can just set, well, the starting style is yellow but the normal color is transparent and then have a transition on it and it'll just automatically do that. That's neat. I think that's cool. It's a bigger deal for things, as they put here, like the dialog element, which this is the thing that unlocks the ability for a dialog element to have an entry animation.

Dave: Mm-hmm.

Chris: Which was otherwise impossible before.

Dave: Impossible. But now you can do it. Then there's this weird allow discrete, which I say allow display to be changed.

Chris: That's another one. It's awful. It's a terrible word I think.

Dave: Yeah. I think interpolate size and allow discrete, they're going to have to start bringing us into meetings because those two are whoof!

Chris: Yeah.

Dave: [Laughter] So--

00:51:09

Chris: Discrete is just ew. Yeah, Dave's allow display to be changed is an interesting one.

Dave: [Laughter]

Chris: Here. I'll do it in two seconds.

Dave: Yeah.

Chris: The idea is that when you do an animation that changes, say, display none to display flex - or something - at what point during that animation does that display value change?

Dave: Mm-hmm.

Chris: It's like a pop quiz. It kind of depends, but it's often immediately.

Dave: Yeah.

Chris: It's often like, "Oh, I'm going from display block to display none. Well, I'm not going to let you fade out the opacity and then change display, you know, then disappear it." It just disappears immediately and it removes your ability to animate anything.

Dave: Yeah.

Chris: The allow discrete doesn't just allow it to be animated. It just changes when it flips over.

Dave: Mm-hmm.

Chris: If you say transition behavior allow discrete, then that display value changes at the end of the animation giving you this ability to fade the opacity to zero and then it gets hidden. Whatever. The worst keyword in the history.

Dave: Lazy display. Lazy display.

Chris: Lazy display. Sure.

Dave: That's what they should have called it. Display equals lazy.

Chris: And I think it's not just like, "Oh, it goes first," or it goes last instead of first. I think it flips because there are times when other properties flip at the end instead of the beginning, and then it flips them. There's some nuance to it that I forget.

00:52:38

Dave: There's one more here.

Chris: Okay.

Dave: Paint order. I don't know if you've ever stacked things and used text stroke or something, WebKit text stroke, because it's not a real property yet.

Chris: Yeah, I hate it.

Dave: But you use text stroke--

Chris: It's the worst property ever because it puts the stroke on the middle of the thing, which nobody ever wants. You should put it on the inside or the outside but never in the middle, and you can't change it and it's only in the middle!

Dave: Right, so they came out with this paint order thing so you can actually say, "Actually, put fill on the top," put the fill color on the top so my text color now overlaps all the strokes there, and it'll lay out almost like you want it.

The example they're using is Super Mario World, Super CSS World. And it looks kind of exactly like the Mario logo when it's done. You can have multiple orders like fill then stroke.

Chris: Yeah.

Dave: So, you can kind of really sort of customize how you're--

Chris: It's doing a little more nuance. But one thing is then you can see the letter as it was designed because the integrity of the letter is maintained.

Dave: Mm-hmm.

Chris: It's essentially saying... It's not really. There's more to it. But it's kind of saying stroke outside.

Dave: Mm-hmm. Yeah. Yeah.

Chris: Which you can do in most design software. It's sort of doing that except for it's splitting the thing in half. If you wanted a 10 or a 5-pixel stroke on the outside, you'd have to set it to 10 because it's going on both sides and then getting cut off by the fill.

Dave: Yeah.

Chris: I know that's hard to visualize.

Dave: Well, I saw Adam do this and then I forgot about it. Then I saw Wes do it, and then I forgot about it.

Chris: Yeah.

Dave: Then I saw Adam do it again, and I forgot about it. And now I saw it here--

Chris: [Laughter]

Dave: --and I'm like, "I'm going to use that!"

Chris: All right. I'm going to try it.

Dave: I'm going to go home tonight and fix my blog, and I'm going to use it. Anyway, I'm just kind of... Dang it all!

Chris: Then it goes over the text shadow as well, so you can now use - whatever it is - stroke, text stroke, which has long been absolutely useless. But if you use text stroke and text shadow and paint order, you can get these really cool triple-color 3D things that are usably aesthetic. Yeah.

Dave: Yeah.

Chris: Anyway, that's the worst mouth blog ever, buddy.

Dave: Oh, well. No, anyway, it's cool times for CSS. I think we've been saying, "It's a hot year, dude! Hot year!"

Chris: Yeah.

Dave: And so, I'm looking forward to see what got into the old--I bet by the time we post this it'll be launched--Interop 2025: here's what's going to go on there.

Chris: Yeah.

Dave: It'll be... I don't know. It's been a good year for CSS. It's been a good--

Chris: What's cool is it doesn't really seem to be slowing down. There's still exciting stuff going on.

Dave: People are committed. People are excited. Yeah.

Chris: I wouldn't doubt next year we're talking about stuff like random.

Dave: Well, I mean we're animating height. We're animating display, Chris.

Chris: Yeah.

Dave: We have container queries. We have parent selectors with :has. Chris, we have it all! We have all the hopes and dreams of 2014 are now alive today in 2024, and it's just great. It's beautiful. We're there. We made it. [Laughter]

Chris: I know. It feels weird to say it. I don't know how much more we need.

[Laughter]

Dave: We're turning into those guys, huh?

Chris: Almost.

Dave: We're going to be like, "Oh, man. We don't need any more."

Chris: Gees. No, I'm sure we do. There's always stuff to think about. But maybe we need a breather or something. [Laughter]

Dave: Maybe. Yeah.

Chris: I don't think people are using this stuff. It takes a while for this to enter the fingers. [Laughter]

Dave: Yeah. For sure.

Chris: To be used when it should be used.

Dave: No. That'll be cool.

Chris: Yeah. All right.

Dave: I'm excited. All right. Well, thank you, dear listener, for downloading this in your podcatcher of choice. Be sure to shart it up. That's how people find out about the show.

Then join us in the D-d-d-d-discord. That's where the party is happening. That's patreon.com/shoptalkshow. Chris, do you got anything else you'd like to say?

Chris: ♪ ShopTalkShow.com ♪