641: Passkey Usage, Writing Code with a Bot, and What’s Up With Java?
We've got a few leftovers from Halloween to process, what's been happening with Passkeys in late 2024, have you tried to write HTML faster than a bot can suggest it to you, CSS anchor positioning and popover polyfills, scroll driven animation thoughts, CSS nesting, and what's the reason for Java?
Time Jump Links
- 00:20 Leftover Halloween candy
- 05:45 Have you noticed increased Passkey adoption in your personal / professional use?
- 24:52 Sponsor: Bluehost
- 25:36 Writing HTML for Email With a Bot
- 33:43 CSS Anchor positioning and popover and polyfilling
- 43:19 Scroll driven animation thoughts
- 49:31 CSS nesting
- 52:11 What's up with Java?
Transcript
[Banjo music]
MANTRA: Just Build Websites!
Dave Rupert: [Dracula voice] Hey there, Shop-o-maniacs. You're listening to a belated Halloween episode. You forgot, me Dracula, hosts the show in the spooky times. Ha-ha-ha-ha-ha. And with me is Chris Coyier. Hello, Chris.
Chris Coyier: I was like, "Oh, my God. What's a werewolf sound like?" Barky?
Dave: [Dracula voice] Oh... yes. You're doing a good job.
Chris: What about... Oh, that's Frankenstein. He talks slow, right? I don't know. I can't do it. You surprise me too much.
Dave: I've got some old Halloween jokes for you if you want.
Chris: Sure.
Dave: What kind of car does a ghost drive?
Chris: A boo--
Dave: A Boo-ick.
Chris: [Laughter] I wanted to get there. I was at boo-mobile.
Dave: What kind of car does Dracula drive?
Chris: Blood fang wing.
Dave: An Accura.
[Laughter]
Dave: Oh, man. That's too--
[Laughter]
Chris: It's like a literation joke. It's very--
Dave: Yeah, yeah. It's kind of like an accent joke that's not fair to Transylvanians.
Chris: [Laughter]
Dave: Hey, hold on. Sorry.
Chris: Is there somebody?
Dave: Yeah, something is weird. My camera is kind of messing up. I don't know what's going on. It's weird. Can you still hear me, though?
Chris: I can still hear you. But yes, I see the camera has mysteriously blocked out. It's all black.
Dave: Here. Maybe I can... Hold on. I'm going to try to fix it. Sorry. We could cut this out.
Chris: Yeah, I bet there are some cables or something. [Laughter]
Oh, my God! Dave! Just... your--
Dave: What?! What's going on?
Chris: Your skin has left and your bones and your blood and all that's left is a skeleton.
Dave: Oh, no! That's terrible! Me oh my!
[Laughter]
Chris: Uh... I'm just on a phone call with a talking skeleton now.
Dave: Yeah, yeah. We're doing good. So, anyway.
Chris: [Laughter] Yeah. Do you got any bones with anybody?
Dave: Oh, I've got bones to pick. Let me tell you.
Chris: [Laughter]
Dave: Did you hear the one... I don't know. I didn't really think it through past this point.
Chris: [Laughter]
Dave: Hold on. There's something weird going on with the camera.
Chris: [Laughter] I can tell Dave's Home Depot budget was--
Dave: Hey, what's up?!
Chris: [Laughter]
Dave: I think I got it fixed now. Oh, here it goes.
Chris: Yeah, it must have been just the camera bug is all.
Dave: Oh, man. Well--
Chris: But that was weird. It turned on X-ray mode.
Dave: Oh, gees. Well--
Chris: Your camera.
Dave: Something spooky going on, I tell you what.
Chris: [Laughter]
Dave: All this Halloween stuff is still lurking around.
Chris: Just still lurking, yeah.
Dave: Yeah.
Chris: I hope you got some good candy. I don't know.
Dave: Starburst. Yeah, eating way too many Starburst.
Chris: Yeah. I'm more of a Dots guy.
Dave: Doctor took a blood test. Doctor says, "Came back all Starburst."
[Laughter]
Dave: Hey, and I'm not going to throw my kids under the bus but they don't eat the candy fast enough, so I'm going to. You know what I mean?
Chris: Mm-hmm.
Dave: It's just sitting there. They got way too much, so I'm just going to eat it.
Chris: Yeah. And they're old enough now that do they have to self-regulate or do you have to step in?
Dave: Oh, they self-regulate. It's fine.
Chris: Yeah.
Dave: But they do candy for breakfast, candy for lunch, candy for dinner kind of thing. But you know.
Chris: Yeah.
Dave: Tis the season. Tis the season.
Chris: Tis the season. Yeah, fair enough. I don't know what our plan is. She just doesn't care that much.
We went to... Not even Halloween-related, we just went to a parade the other day. You ever go to a parade, like a homecoming high school parade?
Dave: Yeah, we had one.
Chris: Just in a small town?
Dave: Yeah, we had one in our town. Yeah.
Chris: Yeah, nice.
Dave: My neighborhood. Yeah.
Chris: That's part of the deal at a parade is they throw candy. You know? Oh, throw candy off the float. Every float in this parade I was at, every float threw candy. There was more candy than Halloween, for sure, just standing in one place, no dress-up.
Dave: Yeah.
Chris: She's like, "Why would we do Halloween? I can just go to a parade."
Dave: This is way less effort. Yeah.
Chris: Yeah.
Dave: We can just do the parade circuit. Yeah.
Chris: Yeah. At first, I was like, "We're getting a lot of this," so I lifted my shirt up, like did the little... Made a little scoop out of the shirt.
Dave: The kangaroo pouch, yeah.
Chris: Yeah, a kangaroo pouch. It was just... I looked enormous at the end.
Dave: [Laughter]
Chris: It was a lot of candy.
Dave: Yeah, my kids brought home a big old bag of candy. They're not touching it. I'm like, "Sweet, dude! Smarties."
Chris: Yeah. They don't have any hands-off ones?
Dave: They don't prioritize it. It's like--
Chris: Oh, my gosh. Grow up, kids.
Dave: I know.
Chris: There's the rules. The Reece's are top tier.
Dave: I know. You've got to put some in the freezer. There's some for eating now, warm.
Chris: Yeah.
Dave: But then some for eating cold later. You've got to think about that.
Chris: Our family is weirdly heavy on Milky Way lovers.
Dave: Okay.
Chris: Which feels very--
Dave: Okay.
Chris: I don't know. To me, they never felt particularly special, but I've come around to it. I'm like, "Yeah. Hell, yeah! Milky Way."
Dave: It's kind of like Snickers without the crunch, and that's a good thing.
Chris: Yeah, a little bit. Mm-hmm.
Dave: A little less texture.
Chris: Got the caramel but no peanuts and whatever. Right. Then the 3 Musketeers just has nothing but pure nugget and, for some reason, those hits less good.
Dave: Kind of makes my teeth tingle when I think about it because it's like--
Chris: [Laughter] Coaty?
Dave: "Ooh, it's just nugget. Just Styrofoam. Yeah."
Chris: Speaking of things you might pass on, we did have a question come in about passkeys.
Dave: Okay. Yeah.
Chris: How opinionated are you about passkeys? It just seemed to be a little round of opinionation was going on about them for some reason. I don't know if anything happened in the world of passkeys, but it was more just like - I don't know - sometimes it just gets in the water and people feel like talking about it. I read a number of posts on it.
But here's the actual question. "Implementation across OS and browsers seems high. Websites don't seem to be making the switch or even offering passkeys as an option. I've noticed limited pass of adoption in Google products. I can't think of any sites that make use of passkeys. I recall Chris has some enthusiasm last year." I think I did.
"Did CodePen evaluate and discover Here Be Dragons? Have you noticed any adoption in your personal/professional use of the Web?"
Yeah, I think I was. I think I drank the Kool-Aid for a minute because they do have some features that are pretty sweet. For one, it's not a password. Passwords are obnoxious. It just... The doors just open for you. You're in. Hoorah! And that feels nice.
Then on top of that, it was like they're extra secure somehow. They can't be phished from you. Isn't that kind of neat? There's nothing to give away. You can't give it away. Wow! Pretty neat.
But I remember having conversations with you, though, that were a little bit like, "Yeah, but what if I switch phones or have multiple computers?" and all this stuff.
The answer seemed to be, "Well, duh. That's because you've got to keep those passkeys in a manager of sorts." The platforms offer them, and they tend to be silos of a sort. They want you to keep it in there. Whatever. Fair enough, I guess.
But the question has been raised. If you're using a really secure system like that, like a wallet or an app or something that keeps them, then are they really that much better than passwords? Now that you're a big-time app user, they're not that much better. [Laughter]
Dave: Yeah. I mean what's interesting is it's kind of like multi-multifactor, right? I have an app I use that I log in with passkeys, and I have to--
Chris: So, that's one auth right there.
Dave: I go in. I click in. Say, "Oh, here's my email," and then it's like, "Oh, that's a passkey. Here, scan this with your phone," so I have to pull out my phone, unlock my phone with my face. Now I'm in the phone, and I go, and I scan the thing. It opens the passkey app, and then I say, "Yep. Log in here." And then it says, "Okay, cool. I'll do it." Then it resolves.
It's pretty cool. I think my only beef with it is if we're getting into pull the phone out of the pocket to log into a website, we've got to have--
Chris: On your not phone?
Dave: Yeah, like on my desktop, right?
Chris: Okay, yeah.
Dave: I feel like if we're getting to that place, we need to really make the session persistent. And I think that's the problem I have with the app I'm using, the Web app that I'm using, that has it. It's like if I click wrong or click back and I actually go back to the login screen, and then I try to click forward, it puts me through another auth flow or whatever.
Chris: Oh, no. Yeah.
Dave: I'm like, "Dude, this needs to be super good if this is the way to log into something." You know?
Chris: Yeah.
Dave: It has to be like, "Oh, I remember you," because it's just a pain in the butt to pull this out.
Chris: Yeah, and if you're logging in on mobile, it's a bit different because then it's--
Dave: It's all on my phone. Yeah, yeah.
Chris: It's not a big problem. It just scans your face again or whatever it does.
Dave: Yeah.
Chris: Even though the scanning of your face isn't really part of the passkey, it's the thing that unlocks the passkey - or something.
Dave: Mm-hmm. Mm-hmm.
Chris: That part always confused me. I'm like, "It's not your face logging in or your finger or whatever. It's something else. But that thing needs to be protected, so it feels like it's your face."
Dave: Yeah. Yeah, so it's kind of like... Yeah, it's basically I'm face signing in, but I'm face signing in to get into my phone. And so, that feels secure. It's secure as anything else on my phone. You know what I mean?
Chris: Mm-hmm.
Dave: And that's a personal device. I feel like that's a good thing. It's a good way to log in. It's just basically like, "We're going to let somebody who knows who you are -- in theory, is you because you are holding the phone -- log into the thing." I think that's--
Chris: Yeah.
Dave: Yeah.
Chris: So, I guess I'm going to say I don't outright hate it. But it does seem like anywhere that offers it, the dream of having it replace passwords doesn't seem to have played out. And so, if you're going to offer it, you're offering it in addition. You're offering it as another thing that you can log in if you want. And the reason you might want to is because maybe you're sold on this idea that it's extra secure, or maybe you like the UX. It feels a little quicker to log in, so you're choosing it.
But the password thing is still there. So then if you explain that to the CTO of a Web app and you say, "Hey, do you want to stop everything you're doing and add another way to log in?" It's not the only way, it's not absolutely revolutionary, it's just more stuff.
It would be fair to say this is just some more technical debt. Would you like it, please? And I can see somebody just being like, "I'm sorry. Wait. What?!" [Laughter] No, I don't want anymore technical debt. I don't get to replace anything? I just get to add it? Meh. Don't love it.
I don't know. Maybe though. We'll see how it plays out. There does seem to be... It went further than I thought it would go. I do see it on some apps.
I think the person writing in here -- RM wrote in -- was that they've never seen it. I have seen it. I think Home Depot maybe has it. I see it in largescale e-commerce apps.
I admit, sometimes I log in and it feels great. It's like, "Ooh, I'm in. Sick. Sweet."
Dave: Yeah. Honestly, I think the next time I roll an auth system, which I don't know when that will be--
Chris: Yeah.
Dave: --but for an app or something, if I were to make something, I would absolutely use it for a side project the next time I need auth because I literally don't want to store your password. I don't at all.
Chris: Oh, you would try to do it and only support it?
Dave: Yeah.
Chris: Like, this is the one and only way we have to get in.
Dave: Only. That's the only way to log in because I don't want to--
Chris: I would love to see how that goes. Where are those stories? It does seem possible to me that somebody is like, "I did this, but then I dropped my phone in the river and I got a new phone. And now the passkey was on that." And then what? Then you'd be like, "Oh, sorry. You can literally never log into that app again. It is over. You need to start a new account or send me your driver's license."
Dave: Is that a real problem? Like if everything is backed up on iCloud?
Chris: That's the thing. Is that real or did I just make that up?
Dave: Yeah, if everything is backed up on iCloud, when I buy a new phone, and it says, "Do you want to just log in?" and you're like, "Yeah," and then all my apps and all my docs and the latest states even are pulled in.
Chris: iCloud, though, technically is optional.
Dave: Yeah.
Chris: It's maybe 100% of people do it, but you know you don't have to use it.
Dave: Right.
Chris: But maybe Apple is smart enough to be like, "Well, if you don't use it, we don't want to be the middleman here. We don't want to have devices at the bottom of rivers that have important passkeys on them. We're going to say that you can't log in with a passkey if you don't have iCloud. If you're not putting it somewhere that's backed up, we're not even going to let you do it."
I don't know. Maybe they do that. That feels like bad journalism. Sorry, everybody. I don't know the answer to that.
Dave: I would think, yeah, because they're kind of broadening the whole passwords, pass app thing, like your shared password keychain, or whatever it is.
Chris: Yeah. Yeah. I kind of want to like it because it'd be free then. You know? [Laughter] Or free at the cost of deeper teeth into you in an ecosystem.
Dave: You're stuck on one OS for the rest of your life.
Chris: But is it good enough? I wonder if people have done that. If you're like me and you're just like, "Whatever--" I've been on Apple since I've been a wee lad, so I'm probably not switching, does it make sense for someone in my shoes to ditch the 1Password thing and just go with the new passwords?
I call it new, but it only feels new because they give you an icon for it now.
Dave: Mm-hmm.
Chris: It's been there forever. But now that there's an icon, it totally feels different. It feels like, "Oh, this like a real actual password manager."
I usually take steps to turn it off because I don't want them fighting.
Dave: Mm-hmm.
Chris: If I'm just going to use one, can I just use one, please?
Dave: Yeah. yeah. It's like... Yeah, they're always... It's like everybody is like, "Can I fill in your password?"
Chris: Yeah.
Dave: "Can I fill in your password?"
Chris: It's still unclear to me to this day when I go to a website and I need to pick a new password, and a little piece of UI pops up, and it has a suggested password. You're like, "Oh, thanks." I don't know who is suggesting that. is it Apple or is it 1Password, because I use both. And I don't really care, but it would be nice to know who is suggesting it. And I'd kind of prefer to--
Dave: Yeah because when I hit save or login, who is saving that?
Chris: Yeah. Who remembers it?
Dave: Yeah, who remembered that?
Chris: And I don't know to this day. Usually, I'm like, "I hope one of you has got it." Normally, I have a job to be done. There's something I'm trying to do (in my mind) and I don't care to keep my password hygiene perfect at that moment.
Dave: Mm-hmm.
Chris: Just let me in because I'm trying to do my job. Then if it becomes a problem later, I know there's some dumb flow and I'll go through it and reset it. But at the moment, I just need to - whatever - pay my Geico.
Dave: Yeah. I don't know, man. I wonder.
Chris: I'm sorry. That was a dumb rant.
Dave: Well, I wonder, too. I wonder if you could do it only... We've all coded a password form at one point in our lives, probably, and it's not fun. Yeah, you get all these rules. You have to do all this. Like we've used a password. What if we just didn't do that part, and our phone was like, "Oh, I do all that. I do all the security bits."
Chris: Oh, you're saying you get a Web dev bonus. Oh, that ties it to this show a lot more clearly.
Dave: You know what I mean? Yeah.
Chris: That if you only supposed passkeys, you'd never have to fail at coding a login form in HTML because there isn't even one there.
Dave: Yeah. Living the dream.
Chris: Ah...
Dave: You never even fill it out. You just give it your email and they're like, "Okay. Well, this guy has a passkey, so maybe give us a passkey." Then say, "Yep, here I am." And they say, "Okay, cool. Good job."
Chris: Yep.
Dave: "Come on in." And that's maybe having the email is maybe the twist there is, like, maybe that's the way the phone in the toilet or the phone in the bottom of a river thing is they can always rescue it via their email.
Put in your email. We'll send you an email link to reset or reinitialize a passkey. You know? Maybe it's that simple.
Chris: Yeah, if you used... If that was your kind of primary key thing for--
Dave: Yeah.
Chris: Yeah. We definitely do that at CodePen. Your email is the main key. Once in a blue moon, we'll get somebody write in and says, "Oh, I made my account with Twitter auth," which we have long since removed.
Dave: Mm-hmm.
Chris: Because screw that. Nobody used it anyway, and it was broken a lot. It was like, "This is worse than not..." [laughter] having it is worse than not having it.
Dave: Elon is like, "It's $200 million a year for this."
Chris: But I get it because, at one time, the social auth would do this thing, like they'd return some kind of token for your app and you store the token in your app.
Dave: Yeah.
Chris: Then if you get that same token back when they auth, then they're logged in. We do not do it that way.
Dave: Mm-hmm.
Chris: We auth you with Twitter, which we're not using anymore. But any other app: Google, GitHub, whatever. What you get back after a successful login includes the email address of the account that was just successfully auth'd. Then we just match against that.
Dave: Yep.
Chris: I'm sure I've explained that before, but it works super fine. When you write back to that person, it's like, "Oh, Twitter login doesn't work." I'm like, "Any of these will work for you," and you can just reset and just log in normally if you want to, too. So, you can never be up poop creek.
Dave: Yeah.
Chris: Email as the key is nice, which just shoehorns to what you were just saying. That might work with passkeys as well.
Dave: Hmm. I wonder if it's true. It seems icy, right?
Chris: Turns out, email rules.
Dave: But then I saw this thread. Alex Russel did another platform adjacency kind of thing, like, the Web is competing with native. You need to understand that. So, what are we--? And we're losing the mobile Web, if that makes sense, versus mobile app, native app contest.
But then somebody... I saw in the thread, somebody was like, "Yeah, but you need Fido. I need Fido 2 security blah-blah-blah," and he was like, "That exists." [Laughter] "It's already there." It's passkeys.
Chris: Hmm... Yeah, that could be cool, too. You do have to write code. But you are abstracting it in the same kind of way. But sometimes that feels good, doesn't it? We're more and more using Stripe elements, which is, I need a checkout form to take payment methods on my app. Stripe, in their great DX ways, says, "Here, use this." And you just load it up, and it loads this payment form that you've seen before.
They're heavily invested in the quality of the UX of that experience. Then you just use it. Which means you didn't have to code it. Isn't that great? It doesn't seem to me there's been a login version of that. Although maybe my experience is light. What did you use it in Luro? OAuth, or something?
Dave: We used Auth0.
Chris: Auth0. Did they provide a component or did you still kind of code that in yourself?
Dave: We ended up coding it ourselves, so that's the thing. That's like the twist with all these, Clerq and WorkOS and Auth0.
Chris: Yeah.
Dave: So, I have very specific problems. But just generally speaking, some are better than others. But they're like, "You don't even... You just drop in a component and it'll work." And I think you can do that if it looks a particular way. But I think you very quickly get into this, like, "Well, I want it to look the way I want it to look."
Chris: Fonts, colors, spacing.
Dave: And so, then you kind of... that little widget doesn't work. I think we actually used the Auth0 one as much as we could, like, we bounced out to an auth server for that - kind of thing.
Chris: Yeah, that's what I seem to remember.
Dave: Yeah.
Chris: Not that it's not still there. You can just go look. But the background of it felt Luro-y, but the actual auth form, you could almost... A seasoned developer could smell that you're elsewhere.
Dave: For sure. And it's just like that's unfortunate. It was kind of like, let's just keep it simple and do everything over there: password reset, all these flows and views and stuff.
Chris: Yeah.
Dave: Let's do all that over there, and then we'll do our thing here.
Chris: It's not that weird. To draw the same connection to Stripe, that's what Stripe checkout is. You literally leave your website and go over. You'd see it. It's familiar. It's like when you can smell a Shopify checkout. You're like, "I've seen this before."
Dave: I've seen this before.
Chris: You've seen the Stripe checkout before, too. It has kind of a two-panel thing when you're on desktop and stuff. Because their market share is so strong, it's actually not... It almost feels better> You're like, "Oh, thank you. This looks very familiar and secure and good."
Dave: Yeah. It's like a Shopify checkout, I think you said. But it's just like, "Oh, okay. Cool. I get it. I get it. I get what's happening here."
Chris: Yep.
Dave: Been to one of these before. But you know. I think the goal is to always do that just to get started. But it does sort of shake the UX. It becomes this... The goal was always to get back around to it and fix it up. But you know.
Chris: Yeah.
Dave: In the idea of keeping things lean, we would leverage this. But to be honest, when you go with these auth companies, they're fine. They're good. But eventually, they give you the shakedown, man. They're like, "Oh, you want to do single sign on to an enterprise? Well, that's a billion, two billion dollar thing." They just start... It costs a whole bunch of money to implement an SSO or get ten SSO licenses or whatever.
Chris: Mm-hmm.
Dave: That was always frustrating to me. I just want to get people to login and then have whole companies log in if necessary. But just a pain.
Chris: Let's say you're going to go down this passkeys round -- just to round this out -- that's not code-free. I don't think it's quite as simple as Auth0. Maybe it is. Maybe you could use Auth0 and only turn on the passkey option - or something. Although, I'm not sure if that's ... or not, but if you wanted to write it yourself, you can. It's just then it's definitely code, and you're probably out there looking for a DevKit or SDK or whatever of some kind. And I seem to remember 1Password offers one of sorts - or whatever.
Dave: Mm-hmm.
Chris: But yeah, it seems highly unlikely that most apps are going to be like, "Yeah! I'll just hand-roll this baby." Absolutely not.
Dave: Yeah.
Chris: You're going to look for something. Now you're writing less code, but you're depending on more code, which is part of the dance of development, isn't it?
Dave: Well, and then there becomes this even worse situation, I feel like, where it's like promises. They're like, "Oh, we have this amazing API and you just hit it," and then you're writing all the code to hit all the API endpoints at the same time. And all the API is doing is saying, "Yep, that's a valid user." [Laughter] I could have written that code but I went with you to make it easier. But you guys got me into a position where I have to hit your API.
Chris: Hmm...
Dave: I made it worse by depending on a third-party for this, so that's where I'm like, "Dude, if I could just passkey it, that would be beautiful for the next thing." I just literally never... I just say, "Cool. Stored your public key in the database. Talk to me later. Come back later." I'll add it. I'll add it to - whatever - one of my new apps.
Chris: Yeah.
Dave: I'll just do it.
Chris: Games.daverupert.com.
Dave: It's coming. We're coming.
Chris: Fantastic.
[Banjo music starts]
Chris: Hey, you got great ideas but no idea how to build a website? Get Bluehost with their AI design tool. You can quickly generate high quality, fast-loading WordPress sites instantly. Once you've nailed the look, just hit enter and your site goes live. It's really that simple.
It doesn't matter whether you're a blogger, influencer, or just starting out your side hustle. Bluehost has you covered with built in marketing and e-commerce tools to help you grow and scale your website for the long haul. And when you upgrade to Bluehost Cloud, you get 100% uptime and 24/7 support to ensure your site stays online through heavy traffic.
Bluehost really makes building your dream website easier than ever. So, what's stopping you? You already got the vision. Make it real. Visit bluehost.com/shoptalk right now and get started today.
[Banjo music stops]
Chris: You know I just delivered my little DX talk again, so I'm in the process of writing it up a little bit. One of the things I talk about in it is that there's... I think we're living it right now, this... You're in a code editor, and the code editor is trying to help you code. Thank you, by the way. I love code editors. They're trying to be helpful. There are different ways that it can do it. For one, snippets are always nice.
Dave: Mm-hmm.
Chris: There are lots of VS Code extensions that just offer snippets. Let's say you write a bunch of Next.js or something and it's got some component generator that spits them out, or you're a Redwood.js user, which is much more kind of opinionated folder model of a component that has the queries and styles and all the different stuff that it does. Very useful. Great. Snippets. Emmet falls in that category, Automattic's snippets, all this stuff. Got to have snippets.
Then there's auto-complete or IntelliSense, the language servers-ish stuff where it's like you start typing an attribute - or something - in HTML. It's like, "Oh, you're trying to write ARIA selected - or whatever," and it gives you this option. You select it from the list. Widely regarded as a great DX concept. Give people IntelliSense. Language-specific, make it smart. Great stuff.
Then along comes AI, and it needs to shoehorn itself into that already (a little bit) crowded space of helping you write code. And I don't mind the completion stuff that it's done. I think whoever first invented that probably deserves a little clap-a-rino. You know? [Laughter]
You know how we applauded pull to refresh and stuff, I think ghost text with tab is up there in the really cool UX things that somebody discovered at one time. But it is at odds sometimes with other things.
There are not that many keys to accept it. What they did is said tab is the key that we're going to do. They didn't roll in and say, "Hey, we're going to do ghost text," and then in order to accept it, you have to hit - I don't know - option G - or something. They just wanted it to be tab.
Well, the problem with tab is tabs fights with snippets sometimes. Autocomplete, I feel like, it generally bound to the enter key. You see the list. You arrow up and down it if you need to. Then you press enter. Then it selects something from autocomplete. But both tabs and AI type ahead stuff are that, so it ends up in a little bit of a fight.
So far so good ish, in my opinion, because AI takes a second. A lot of times, if you have a snippet in mind, you'll beat the AI text appearing. Then the snippet kind of wins. If you know you want the snippet, just be quick about it and you'll get it.
Dave: [Laughter]
Chris: But as AI gets faster, which seems to be happening, that fighting gets worse. Then you've got to wonder where we're going to go with that. Not to mention, type ahead isn't the only way to use AI. There's a lot of, like, selecting and opening up a chat interface and the chatty stuff is a whole part of it.
There's a lot more UI happening with "help me code" than there was. I say all that to say that John Ellwood wrote in and says, "You guys want to try what must be the most maddening experience ever?" This is very specific. He says, "Editing a PHP file that uses tables for HTML for an email and... wait for it... using Codium or a little AI buddy of choice with suggestions turned on. Maddening!" he says.
It doesn't really explain why, but it must mean that the thing that he's trying to do is such a kind of somewhat strange combination of technologies, meaning it's PHP that's really HTML that's in a table for an email, AI probably has no idea what he's trying to do, and all the suggestions probably suck.
He writes, "Do you guys ever play beat the bot where you put your cursor on the next line and try to type what you want before the suggestions come up and throw everything off?"
Dave: Oh...
Chris: That's funny.
Dave: That's funny. Yeah. Man. It's a battle, man. I sometimes wonder if it's getting better or worse.
Chris: Yes!
Dave: That's kind of my current feeling on it. I feel like what it's showing me right now, like my most recent memory, is serviceable code. But it's all wrong. [Laughter] All the variables are wrong, class instances are wrong.
Chris: Mm-hmm.
Dave: But it's ballpark correct. But it was definitely not the right code. Does that make sense? It's like, "Okay, could hit tab and finish this."
Chris: Yeah. I almost prefer when it's very wrong than when it's very subtly wrong.
Dave: Yeah! And so, it's like I could hit tab and fix this or just keep typing and I have it. But then I'm going to hit tab at some point and probably accidentally ... something.
Chris: Yeah. In the early days, they wanted you to cycle through them, too. They said, "Here's a selection," but they were less confident about what it was, so they're like, "Or hit command-K," or whatever it was, to cycle through different possible suggestions, which was okay, but it feels like that UI didn't hit real hard, so I see that less and less. It's like, "Take it or leave it," kind of thing.
Dave: Mm-hmm.
Chris: I don't know. That's why it's interesting, though. And it's fun to think about because it feels... At least I can think about AI and not get frustrated because we're just talking about a DX and UX concept here. I don't have to trouble my mind with everything else that bugs me about AI. I could just focus on, like, "Well, what's the experience like?"
Dave: Yeah, is the experience good? I think, so far, I do use it, Copilot, and so I'm fine with it. It's generally pretty good. But there are times where it's like, "Oh, man. I wish you'd get out of my way," and that's a bad place for a tool.
Chris: It is. From day one, I was like, "Can there be a setting?" and I don't take offering, "Can there be a setting?" lightly. Settings are a pain in the butt, and I'm sure most support emails that start with, "Can you add a setting?" the answer is absolutely not.
But it seemed to be a valid one to me because I wouldn't know where else to express this. But when I'm writing a comment -- just my preference; if you like it that's fine -- don't do any AI. I need to think about what I'm writing. When I type //, do not suggest what I am trying to say. I have something in mind that I'm trying to say that's very specific to me and my team.
What it usually tries to do is just kind of explain what's going on in the code.
Dave: The block of code? Yeah.
Chris: That's my least favorite kind of comment. Usually, my comment is, "This needs to be here for X, Y, and Z external reasons that you'd have no idea why," or whatever. Usually, my code comments aren't like, "The following code is a loop. It loops over the person's object and adds the address field." I can see that! You know?
Dave: Mm-hmm. Mm-hmm.
Chris: I hate code comments like that that just explain the next line of code.
Dave: No, I mean a lot of times my code comments are like, "Uh... Chrome version 125 through 128 support his CSS property and it's weird."
Chris: [Laughter]
Dave: But other ones don't.
Chris: Right. Yeah, yeah, yeah.
Dave: You know, so it's all this... Yeah. I've been doing a deep dive on CSS anchor positioning and polyfills and all this, working in that world: popover, anchor positioning, polyfilling.
Chris: Wow! You're deep in it, huh?
Dave: Man.
Chris: Cool.
Dave: Oh, it's... I wish there were no cuts, but it is pretty interesting. [Laughter]
Chris: Yeah?
Dave: Especially in Web component world where it's like the anchor name doesn't traverse the ShadowRoot. Now your styles can't exist. They have to be added to the document - or whatever.
Chris: Oh, wait. I'm not sure I totally followed that. Is that an interesting one to follow?
Dave: You have to inline the styles, right?
Chris: Yep.
Dave: Well, and then to get the anchor to work, or you can adopt a stylesheet in the parent - or whatever, like make one with the IDs all looped up. You can do that.
But then there's this added twist where the polyfill, you have to do all that work before the polyfill runs. Now you have to, like, "Okay, cool. We have to get this to work."
Chris: It's like if you need a DOM element inside the Web component to anchor to something outside of it? Is that the situation?
Dave: Yeah.
Chris: Ooh... Hmm...
Dave: If you wanted to put all of my anchor styles inside the Web component, it doesn't know. It's lost reference to the anchor.
Chris: I see!
Dave: It's like, where am I anchoring to because I've never heard of anchor foo.
Chris: Oh, I do not envy that. Right.
Dave: Yeah, so that's less rad.
Chris: I could see that.
Dave: But then you just put it all in the style tag. And if you're using position area, everything works great.
Chris: Yeah.
Dave: Which was formally called inset area in Chrome 125 through 128. So, you need an @support thing, and then you need to variablize all your positioners. Whatever. We'll figure it out. [Laughter]
Then we do... Then you do this... But, yeah, getting it all to work in other browsers and stuff, too, was kind of tricky. It's been kind of a fascinating sort of--
Chris: Yeah because it's really only in Chrome (right), anchor positioning.
Dave: Yeah.
Chris: Generally, yeah.
Dave: Credit to the Allbird. [Laughter] Allbirds on the shoes. Oddbird polyfill, it's really good. Actually, my coworker Zack E. committed some code against it.
Chris: Nice.
Dave: So that we could just apply it to a specific element, not just like, "Hey, scan all elements ever."
Chris: Yeah.
Dave: We could just be like, "Just this element, please."
Chris: I wonder if there are less people making polyfills these days because stuff moves so fast that they're like, "Why would I write a polyfill? It's just going to be done in less than a year."
Dave: I wonder. I wonder if there's... Yeah. It's funny to sink all this time in, and you're like, "I know it's going to come out in Safari TP."
Chris: Yeah.
Dave: It's just going to show up the day I hit merge.
Chris: [Laughter]
Dave: It's going to show up, and then I'm going to be sad.
Chris: Yeah. I'm sure it's probably no way to think, though, because - whatever - people have old iPads with locked versions that they keep for ten years.
Dave: Oh, brother.
Chris: You'll be helping them.
Dave: I should send you screenshots. I released an app called Mundango, a little bingo app for real life, boring things. It's fun. It's cute. I liked building it. I had fun.
Then the first thing, dude, the first five minutes, I'm on an iPhone X that's version locked at iOS 16.7, and this doesn't work. It would be a pity. It's a big pity that it isn't universally inclusive or something.
I just was like, "Ew." I don't know. I fixed some of it, and so it was CSS nesting and my use of Tone.js for audio wasn't working. But I just kind of... I don't know. This whole thing where you kind of guilt trip something into implementing a thing for you is not my favorite cup of tea.
Chris: Yeah.
Dave: It's not my--
Chris: But they used your kryptonite, right? The inclusivity or accessibility or whatever.
Dave: Yeah.
Chris: They're trying to use the things--
Dave: Manipulative. It's gross.
Chris: Yeah.
Dave: It's disgusting, and it worked. But no.
[Laughter]
Dave: But what I had to do mentally was be like, "This is purely a technical discussion." Their device is vendor locked at a certain browser version. Can I accommodate it? Sure. Should I? Okay, fine. I will.
Chris: Yeah.
Dave: But it's just kind of this, like, you don't need to pile on extra guilt when it can just be a technical conversation.
Chris: Mm-hmm.
Dave: This element needs the ARIA role blah on it. That can just be a statement. You don't need to be like, "Because you hate blind people." You don't need to add that in there.
Chris: Right.
Dave: Just say the minimum that you need to get it done. You know what I mean?
Chris: Fair enough.
Dave: I'm grumpy. I'm grumpy about that.
Chris: It gets there. With anchors, do custom items come in? When you give an anchor name, give something an anchor name, do you do, like, --myanchor - or whatever?
Dave: Mm-hmm.
Chris: That's always... That's been funny. Not funny. I can see it confusing people even though it really probably shouldn't or doesn't need to - or whatever. It looks like a custom property, and you see --.
It's been a lot of years now in all of our brains who go, "That's a custom property. Oh, neat." But lately, more and more stuff has been coming out that uses that -- syntax, but it's not a custom property. It just means I'm inventing a name for something, and I like it. I think it's good.
Dave: Yeah.
Chris: I don't know if the confusion is the right word then. But it came up for me just this week. With an anchor name, you might do it or do you have to do it?
Dave: Right now, as of today, you have to.
Chris: You have to do it.
Dave: You have to say... On the button, you say anchor name equals --
Chris: --something.
Dave: My button - or something.
Chris: Yeah.
Dave: Then on the popover thing, you say position anchor://mybutton. And so, that's what connects them together.
Chris: That's what connects the two, and you have to use the -- thing because it's a thing in CSS that's not a custom property. It's called a custom ident.
Dave: Yes.
Chris: Right? Is that the right terminology?
Dave: Yes.
Chris: Okay.
Dave: And so, there is a proposal, and I think it's going through via TPAC, recent TPAC stuff is to add an anchor attribute on an element. So, you could say button ID my button, and then, on your popover, you say div popover anchor equals my button. You make the anchor reference there.
Chris: In the HTML, you mean?
Dave: In the HTML, yeah.
Chris: Oh, okay.
Dave: And so, your styling, you would say position area on the div popover - or whatever you want to do. And then something like there's also this anchor thing where you say, "An anchor function in CSS." I don't know if you've seen that. It's kind of weird.
Chris: Is that the try syntax, or whatever?
Dave: There is a try syntax, and it used to be try options but now it's try fallbacks, I think.
Chris: Okay.
Dave: But you have an anchor function like anchor()--mybutton,left, and that'll anchor it to the left of the button or to the button's left. Sorry. You anchor to the button's left.
Chris: Mm-hmm.
Dave: But then with this new anchor attribute, that would become anchor left, which is kind of cool.
Chris: Mm-hmm. Mm-hmm.
Dave: Anyway, we're getting close, I think, to being able to declaratively add a popup and attach it somewhere, so that would be kind of cool.
Chris: Yeah.
Dave: We're not quite there yet.
Chris: I feel like I am tapping my fingers on this a little bit, not that... I almost just watch it. I feel like I have a bunch of production stuff that I need it for, so I do have to check myself sometimes. But I do feel like that emotion comes up in me sometimes where I'm like, "Okay. We have popovers, so where's anchor positioning plus popovers? Popovers are useless without anchor positioning.
I almost have to stop myself from thinking that. But I do think they are super tight at the hip, and it's super dumb that you can't anchor a popover yet. I feel like anchor should have dropped first almost.
Dave: Yeah.
Chris: Whatever.
Dave: No, I think it's the harder problem. But I think--
Chris: It's only the harder problem because now all of a sudden we have top layer and we just use it all the time now.
Dave: Right. Right.
Chris: Which is pretty nice.
Dave: I'm looking at this Riverside UI. There's one, two, three, four popovers on the bottom. There's one... That's a dialog. One, two popovers. There's a tool tip in the top and then....
Chris: Are they anchored, Dave?
Dave: They're anchored.
Chris: Yes, they are anchored.
Dave: And so, it's like a very useful Web platform feature. We're just not there yet.
Chris: Yeah. Okay. I take it back. We do need this immediately.
Dave: Yeah. Hopefully, it makes waiting eagerly on interop 2025 here.
[Laughter]
Dave: But--
Chris: The one I was looking at with custom idents that I didn't... I guess I just didn't realize this was a thing. I didn't because I wrote a whole blog post about a way to get around it and then needed it. Okay, but now I've jumped ahead too far.
Scroll driven animations. Now, instead of giving a duration to an animation, you can say the timeline for that animation is this expression of scrolling, essentially. It can be based on how far an element is scrolled. That's what's called a scroll timeline. Or it could be a view timeline, which is that element is experience in the viewport. Has it just arrived in the viewport? Is it leaving the viewport? And with percentages and all this controllable stuff.
There are two different types of scroll driven animations. One is just basically zero to 100% how far it's scrolled, and the other one has to do with its visibility in the viewport currently. They're both quite useful. The view ones are almost cooler, though.
Dave: Mm-hmm.
Chris: Because it seems like more newfangled in a way that scroll timelines was easier to write in JavaScript and whatever. But the view ones are really cool. But notably, both of them can have a custom ident on them. And I didn't really know that.
You don't have to do that because a lot of times you're just adding an animation to itself, like, "Oh, you want an image to fly in? Then put a view scroll animation on it, and have it adjust its whatever, translate X property to fly in from the left when it comes into view. That's very straightforward and has nothing to do with a custom ident. But the reason you would give a scroll timeline or a view timeline a custom ident is because you want some other element to react to its scrolling or position in the viewport, or something.
Dave: Mm-hmm.
Chris: Isn't that interesting? You can have some totally other element react to the scrolling of a different element, a totally unrelated element.
Dave: Yeah.
Chris: Pretty interesting, and it happened to me because I was trying to do something really simple. So, imagine a section, section, section, section, section down a blog post. It's like a landing page or something. You can imagine that you'd want a view scroll driven animation on each one of those sections like, "When this section is visible, I want you doing some special stuff."
I had this really simple idea that when you're scrolling one of these sections and when it's the active section, there's a pull quote that's related to that section that becomes visible. Maybe it scales up or something. But then when that section is gone, it's done and some other section takes over.
Well, now you have this problem because the animation needs to be on the pull quote.
Dave: Mm-hmm.
Chris: But the section is the thing that's scrolling. There's a disconnect between the elements.
I was like, "Well, here's how you do it. You make custom properties. And you just slap custom properties on the section. Those are the things that you animate. Then all the children of itself can just use those custom properties for what it needs to do." Now that's valid and works. But I had missed this and Bramus pointed it out to me. He's like the scroll driven animations master. You can just name the animation.
Dave: Yeah.
Chris: Name the timeline, and then other elements can use it. Now they do have to be children, which I found a little unfortunate. Your anchor stuff is not like that. Anchors can just be wherever, can't they?
Dave: Anchors can be wherever. Yeah, yeah, they can.
Chris: Yeah.
Dave: It's kind of like I could chuck all my tool tips at the bottom of the page like footnotes and then I could anchor them up.
Chris: Anchor them wherever. Yep.
Dave: Yeah.
Chris: There's no connection. There is a connection in the view timeline stuff. If you're going to use a named scroller view timeline, it needs to be looking up the DOM.
Dave: Sure.
Chris: And finding it. I don't know why because, immediately, when I learned this, I put two different elements on the page. One scrolled and one was just sitting there. I wanted to just have it animate a number or spin or something. But it didn't work. But I realized because they're siblings. If they're siblings, it will never work.
I don't know about never. I shouldn't say never. But it seems unlikely. They've got to be--/p>
Dave: The child can use the animation of a parent.
Chris: A parent, that's right.
Dave: But it can independently, yeah.
Chris: Yep, yep, yep. I don't even know if there can be multiple. Maybe. I didn't dig that deep into it. But I liked the idea of naming it and then the idea of custom idents was in there because you have to use the --name thing to give it.
Dave: Oh...
Chris: And you have to declare which direction the scrolling is.
Dave: It makes me think container queries should use this -- ident.
Chris: Yeah, maybe because right now you do container name, and then you just make up whatever as a name. Why didn't they use custom idents? Don't know.
Dave: Maybe it didn't exist yet.
Chris: Maybe. Yeah.
Dave: Interesting world.
Chris: Don't mind it.
Dave: I wonder if it has a special meaning than I am thinking of because I think of it as a fancy variable name. You know?
Chris: Yeah. Does it do anything special?
Dave: Does it do something...?
Chris: Does it warn you if you accidentally reuse it?
Dave: Yeah.
Chris: Does it yell at you in a neat way?
Dave: Huh.
Chris: I don't know.
Dave: Well--
Chris: Well, that's it. Thanks for the tangent.
Dave: Yeah.
Chris: That was fun.
Dave: Yeah. No, it's interesting. I need to... For a work thing, I have to present on kind of new fangled CSS stuff, so I kind of have this... I'll probably scam a lot of your talk. [Laughter] But I think it's also just kind of like, "Here's stuff you can use," and it will make a huge difference in how you're doing... how you're coding.
To do one of those little UI scroll UIs where every paragraph floats in and flies in, way less code.
Chris: Yeah.
Dave: You're just doing a little bit of sprinkling.
Chris: It really is the syntax for that is pretty chill.
Dave: Yeah.
Chris: Kind of a fan.
Dave: I think it just changes out. It changes a whole lot of what we can do easily.
Chris: You know what we can do? You know how with container queries--? Here's... This is niche syntax that would be way better in video, but we're going to mouth blog it. CSS nesting exists now, so--
Dave: But not on Safari 16.7. [Laughter] Go ahead.
Chris: Oh... Great caveat.
Dave: Yeah, yeah.
Chris: That's the world you live in now. And so, if you're not processing it... Let's not get into it.
CSS nesting, you can write on an element. At the top level of this nesting is a container. Then say - I don't know - whatever - Dave's component / inline size. Now you have a container. Now you can style anything that's a child of that container. Crucially, you cannot use a container query on that very same element. Everybody knows that I hope. That's a little gotcha with container queries.
But with CSS nesting, you can just write @container and then whatever, width is greater than 400 pixels - or something - within it. You don't even need the container name or anything. It's just an anonymous container, kind of. Because of the CSS nesting, it just implies you're talking about this element.
Dave: Oh, really?
Chris: Like a media... You know how media queries are the same.
Dave: Yeah, yeah.
Chris: You nest the media query inside of it, and that's fine for whatever reason. Yeah, I think that's nice.
Where was I going with that? I don't know. I can't remember. I like the idea of anonymous names like that. That's what happens... When you don't name a view timeline or scroll timeline, it's the same kind of theory. It's anonymous.
Oh, that's where I was going with it is I don't think keyframes work that way. In Sass, you'd see that. People would write a keyframe way nested in.
Dave: Mm-hmm.
Chris: Because it's relevant to that component. But it didn't do anything. It just bounced it all the way out. You still had to name the keyframe and all that.
I wonder if you could, with a scroll or view timeline, you could write an anonymous keyframes animation that just doesn't even have a name but the implication is that it just automatically applies to that animation. Probably not. Ugh...
Dave: I feel like it needs a name, but--
Chris: It needs a name like it needs a name. [Laughter] But there's a bunch of other features that don't need names, so why does this need--?
Dave: Well, but you can also just point it at, like, @keyframes and be like, it's just a normal animation but you're doing a scroll. It's scroll-driven. I forget what the syntax is.
Chris: Yeah. It would just mean that, in the animation property when you call it, you just leave the name off.
Dave: Mm-hmm.
Chris: Be like, "Oh, inherit the keyframes that are within here." It seems highly unlikely, but maybe.
Dave: Maybe. Maybe.
Chris: Maybe. Let's end with one really unusual one where we have no expertise in it--
Dave: Perfect.
Chris: --from our old pal Simey de Klerk from sunny Cape Town. "What's up with Java," Simey writes in. "Why is or was it so successful?" Would you consider Java successful today as a language?
Dave: I would.
Chris: I would, too. It's huge.
Dave: I mean it's huge. I think everyone... Java's big deal was it was a kind of... It was object oriented programming.
Chris: Object oriented. Heck yeah.
Dave: In a very modern syntax. You have to kind of flashback to the late '90s here. Everyone is kind of like writing a bunch of C++ or Pearl or stuff like that.
Chris: They're still around, so--
Dave: Which are still around.
Chris: Yeah.
Dave: But Java shows up, and it's like you just install the Java runtime and then blam-o, we run your Java.
Chris: Mm-hmm.
Dave: An you build a jar, and then we do that. You know?
Chris: Yeah.
Dave: I think it has the same fingerprints as NPM. It's kind of this "write once, run everywhere" thing. But this idea you could just grab little code packages. Not quite packages, but I'm thinking of NetBeans or something. [Laughter]
Chris: Wasn't that just based on the popularity of the language, though? Like, it got popular so people made stuff for it.
Dave: I think it got popular, so people made stuff for it. So then, people said, "Oh, this is the best one because it has stuff."
Chris: Has the most stuff. Yeah, it's a little cyclical in that way. [Laughter]
Dave: Yeah, so that's where I say it's like NPM. It had modules, basically, that people could pull in and buy.
Chris: Yeah.
Dave: It had a whole enterprise arm where you could buy stuff. I think, as of today, there's a bunch of software written in Java. People still write Java and love it.
Chris: Yeah.
Dave: Angie Jones, I'm thinking of.
Chris: Yeah. I think it's still fairly well liked to some degree. I'm sure it's hated in some worlds, too. But it's just so big that ... [laughter]. But you don't hear of hot new Web development tools written in Java or anything. If you're all Web all the time, I don't think you see it very much.
Dave: No. Yeah, the Java world is different. You have to download a tomcat from a guy named Tom in the company who has it working. And you copy his tomcat into your--
Chris: Yeah.
Dave: --JetBrains, and then it works.
Chris: Yeah.
Dave: But only Tom's. Not anyone else's.
Chris: And crucially, the big... What seems like to me the big thing is that Android... If you're going to write a native Android app and do it just as bare metal as you can, it's Java.
Dave: Java, yep. And so, there's been other, like Kotlin, which is sort of like Android's Swift. In Apple land, you can write objective C, but you're going to have a better time writing Swift, I think. I think that's kind of the idea. There are more modern languages that are going to feel better and make more sense.
Chris: Mm-hmm.
Dave: But the key thing about Java is everything is an object. It's really strict about that, I feel like.
Chris: Yeah. If you didn't know this, it has absolutely nothing whatsoever to do with JavaScript. It's just a bad name on JavaScript's part. Sorry about that.
Dave: Came out about the same time.
Chris: Yeah.
Dave: And you could use JavaScript to load a Java applet or maybe that was just an object tag. I'm thinking of the picture with the shimmery lake underneath. Those are so cool.
Chris: It's why I dropped out of being a computer management, computer systems person. As soon as we got into Java classes, I mean literally classroom classes, I just hated it. And it was just at the time. Maybe I wouldn't now.
I bet if I took a Java class now I'd probably enjoy myself just because I'm learning something interesting that I have no big connection to. I probably would. But for whatever reason, at that time in my life, I was just like, "I hate this. I know a couple of other languages. I like them okay. Why do I have to learn this one? It looks really complicated. Blah! It doesn't work good on my Mac." That probably was a big part of it.
Dave: Yeah. No, no.
Chris: I was just like, "Screw it. I'm out." I literally quit.
Dave: Ooh! Oops!
Chris: [Laughter]
Dave: Yeah. My computer science department has computer science for one year at University of Texas at Austin before changing to becoming a Japanese major.
Chris: Mm-hmm.
Dave: I learned Pascal.
Chris: That was my favorite, dude! I loved it. I thought it was so clean.
Dave: It's okay. It's not great. Then I learned Haskell, which is all cool.
Chris: Weird.
Dave: Nerds love that now. I learned Scheme, which is also a Lisp variant. Then I quit. Then the whole department is like, "We're teaching Java first year now." And I was like, "Dude, I would have stayed in if that was the case."
Chris: Oh, that would have got you.
Dave: Because I was like, "Dude, I'm not going to spend my life writing Pascal." You know what I mean? [Laughter]
Chris: Right. Yeah, I like the syntax where you could clearly tell it wasn't... There were not a lot of people making money right now.
Dave: No. It's like green mainframe screens. I'm not going to do that, dude. I need to make money and Dell is right down the street, and so I was just like, "Clearly Java is the right pick." Right? But they didn't do that. So, anyway. Oh, well.
Chris: Oh...
Dave: Oh, well.
Chris: All right. Well, thanks for the questions, everybody. Really useful. Thanks.
Dave: Yeah. Thank you.
Chris: Happy Halloween super late. Probably several weeks ago.
Dave: Yeah.
Chris: Probably forgot about it.
Dave: Belated Halloween. We appreciate you. Be sure to shart this up in your podcatcher of choice. That's how people find out about the show. Follow us on... We're doing Mastodon, but Bluesky has got the legs right now.
Chris: It does.
Dave: Then it's holding the chaos stone. That's fine. But we're not on that one. But then you can join us over in the D-d-d-d-discord, patreon.com/shoptalkshow. Thank y'all who support us through there. Chris, do you got anything else you'd like to say?
Chris: Hmm... ShopTalkShow.com.