It's difficult enough to keep up with new web things, even when it's your job. How do Chris & Dave do it? Dave's blogging on spicy sections, Chris' Cloudinary issues are resolved, and there's some Apple problems to deal with.
Time Jump Links
Episode Sponsors 🧡
The Best Real‑time WordPress Backup Plugin. Save every change and get back online quickly with one‑click restores.
If you make money from your site, or spend hours perfecting content, you need WordPress backups. Protect your investment by getting your site back online in seconds. Our automated backup plugin is powerful enough for pros, but easy enough for beginners.
Project management has never been easier We bring the flow to your software team's workflow. Plan, collaborate, build, and measure success with Shortcut.
We're project management without all the management.
MANTRA: Just Build Websites!
Dave Rupert: Hey there, Shop-o-maniacs. This is a spooky episode of the ShopTalk Show. You forgot this comes around every year, but I'm Dave Dracula Rupert and with me is Chris Frankenstein Coyier. [Devious chuckling]
Chris Coyier: [Devious chuckling] Me eat divs.
Chris: I don't even know. What does Frankenstein eat? Bolts?
Dave: Electricity. He wants his bride. That's the big one.
Chris: Oh, that's a good point. Yeah. He said he wants to get married.
Dave: Yeah. Yeah.
Dave: Been there.
Chris: I don't know why this made me think of it, like, what does Frankenstein eat? I'm like, what do other HTML elements eat? Do you know?
Dave: Hmm. This feels like a segue. [Laughter]
Chris: It's not, really. I just saw this. It was like somebody built "Can I Use" but for can I put--
Dave: Can I nest?
Chris: --this HTML. Can I nest?! Do you see that going around?
Dave: No. No, I didn't see it.
Chris: It was pretty cool. I have literally never. I've had bugs with this, but I've never thought to reference documentation to see what's valid or what's not. But you put a parent element and a child element, and it tells you if it's cool or not.
Dave: Oh, really?!
Chris: Is that okay? Dave, can you put a div in an H1? Is that cool?
Dave: I think no.
Chris: No! [Laughter]
Dave: Because you double blocked yourself, right? Kind of. Yeah.
Chris: Yeah, but you can put a div in a div, so who cares?
Chris: But headers, for whatever reason, they don't want to be in there. And they literally will just get booted out.
Dave: Yeah. Isn't that weird?
Chris: Yeah, it's pretty weird.
Dave: Yeah, there's definitely -- I've been in the open UI there talking about new elements, potential elements, and you really have to think a lot about this. This idea of compound elements has come up, elements that depend on other elements or sets of elements.
Chris: Like you have to put a summary in a details - or whatever. It doesn't make any sense to not have it there. A T-head only goes in a table.
Dave: Mm-hmm. Or input, right? It has a buddy called label. Input type = checkbox. You know?
Dave: Or radio.
Chris: But you can't put anything in an input.
Dave: You can't put anything in an input. No, it's kind of a self-closer. [Laughter] But there's another one that kind of goes with that (the input radio and checkbox) is fieldset. We often forget that, but that kind of labels the whole group of checkboxes, right? Then with fieldset, you have a legend.
Chris: Does it? Do you not even need a label with a checkbox if you put a fieldset in a legend element? Or do you still need a label per--
Dave: I guess if it's like a group of checkboxes, you probably would want it.
Chris: Because they're all the same. If it's checkboxes, if they all have the same name attribute, then one label for that name labels them all? No. That's not it.
Dave: I guess you only need it for radios because checkboxes label is usually, "Do you agree to this terms of service?" "Yes." Or whatever. But I could see a situation where it's a group of checkboxes, like, "Check all the things you like." [Laughter] "What are the fruits you like? Check them all off."
Chris: Yeah, it's a label for a group of things.
Chris: Yeah, okay.
Dave: So like fieldset and then legend comes with that, too. You'd never use a legend without a fieldset. Right? But there's been some talk about possibly (in the open UI) this idea of a radio group where you could not use a weird fieldset.
Dave: And you could kind of group radios.
Chris: People have shied away from it because it has some quite weird layout implications where the legend is halfway--
Dave: Obscured. Yeah.
Chris: Centered between the fieldset.
Chris: Yeah, pretty weird.
Dave: Sometimes you want a radio group, but you want it in a table. You know what I mean?
Dave: You don't want it in -- or just for example, but if you wrap that, you can't shove a table or a fieldset into multiple rows or something like that. The use case is more business-y.
Chris: Yeah. You do gotta think about it. Then the failure state for them is sometimes unnoticeable. I think if you put a div in an H1, I don't think you're going to -- it's probably not going to manifest itself poorly all that much.
Chris: I had it being asked just this week when I was doing all that e-book stuff because then it takes the HTML, digests it, and needs to turn it into another format. Even if the problem didn't manifest itself on the Web, which it didn't, it did when it tried to make it into another format. It chocked on that.
Dave: Oh, really? Hmm.
Chris: Markup, and it freaked out. But sometimes you have to think about it and sometimes you don't. Like an LI makes no sense all by itself.
Chris: And any other element that isn't an LI doesn't make sense in a list, except for definition list, which allows divs in it now. There are all these little rules about HTML you've just gotta know.
Dave: Yeah. Yeah, it keeps -- yeah, it surprises. Then you're no stranger to deprecations of platform features. But you learned a rule and you think it's the truth for the rest of your life. But then it's like, "No, you can put a div in a DL now." [Laughter]
Chris: You literally don't get a memo.
Dave: You don't get a memo. [Laughter] It just happens, and then somebody writes a blog post about how you're dumb for doing it the dumb way. Ah, well.
Chris: Yeah. You've brought this up a number of times. It's sometimes like we keep up to date with this stuff almost as a profession.
Chris: And it's still hard for us sometimes.
Dave: Yeah, I mean we are a very pundit class-- [laughter]
Chris: Yeah. [Laughter]
Dave: --of Web development. But you and I, just you by nature of CSS-Tricks and actually staying on top of CSS specifically, you have your almanac and everything. You're always on the hook for good tricks or whatever. And you have inbound blog posts. "Hey! Read about this new feature," or whatever.
Me, I am interested in this big Web thing, and so I try to track it.
Dave: I subscribe to different browsers, RSS, and stuff like that. We pay attention, you and I. But the volume that we miss seems--
Chris: Yeah, and I'm still regularly surprised.
Chris: Like, "Oh, crap! That's how that worked?" I mean remember when I mentioned -- What were we? In a video, probably.
Like and subscribe on YouTube.
Dave: Yeah, like and subscribe.
Chris: Is at supports with the selector. I didn't even know you could do that to begin with, let alone I checked the browser support and it's like, "Yeah, I'll browser support that."
Chris: The selector function. I was like, "Okay. Cool."
Dave: [Laughter] What?!
Chris: Got it.
Dave: Yeah. Today, in the D-d-d-d-discord, somebody was showing if you do a selector for, like, an attribute selector, like IMG.
Dave: But your angle brackets or your square brackets--
Chris: Square brackets, yeah.
Dave: Then you say - whatever - source*=https, that's going to match.
Chris: Yeah. You do a *= select all secure links.
Dave: Secure links or images, yeah.
Dave: Or alt - whatever. But you can add a space and then type the character "I" to make it case.
Chris: Before the closing square bracket, yeah. It's case insensitive.
Dave: To make it case insensitive. I didn't know that existed. I mean I doubt I'll use it, but--
Chris: Until today?
Dave: Well, until last week. Somebody posted it. I saw somebody post it, and I was like--
Chris: Oh, yeah.
Dave: "No way?! Really?!"
Chris: Oh, it's great.
Dave: I haven't used it or needed to. Everything has been lower case.
Chris: No, the most common one is angle brackets and then you go something like, yeah, source or href and then $= means ends with.
Chris: Then .pdf or something. You're trying to select all PDFs, but you don't want to write five selectors that, like, "Oh, but what if it ends in capital PDF?" That's still a PDF, but it wouldn't select otherwise, so you put the "I" in there.
I thought of it just while I was doing the selector when I was looking at that selector API, the function one for at supports, because I was like, "Oh, yeah. That's an interesting one. Maybe that would be an interesting use case for it." Then I look at Can I Use, and they're like, "Nope. Everything supports it."
Dave: Really?! Wow!
Chris: There's not that many -- there's not that much cross-browser weirdness with selectors.
Chris: It's much more common that it's a value or a property than it is a selector.
Chris: A little bit of weirdness, like there's full-screen is a little weird - I looked up.
Dave: Full-screen. WebKit has its own deal.
Chris: That's the thing that goes with dialog.
Dave: Yeah. Then there's even, like, to get an auto-playing image, you have to do -- so, an auto-playing video, you can't do it on mobile Safari and stuff like that, right? But if you do muted loop auto-play.
Chris: Yeah, those are all--
Chris: Exactly. There's a soup of attributes.
Dave: There's a soup of attributes that trigger a GIF-like loop of a video.
Dave: It's actually more performant.
Dave: You should probably not be using the GIF format. You should be shipping MP4s, very crunched-down MP4s. I think even GIPHY does that automatically because it's so--
Chris: Oh, yeah. Twitter does that. Everybody does that now. It's just the standard. Even if you upload a GIF, it will turn it into a--
Dave: An MP4, yeah.
Chris: A video.
Dave: And so it's just interesting. There's this soup of attributes you can do to trigger. That would be a good blog post. [Laughter] Like Attribute Soup: What attributes do you need to trigger some different functionality?
Chris: Yeah. I do have to look it up every time. Oh, yeah. [Laughter] What's the--? Let's play the game. What do these attributes even do? Even plays in line.
Now that I get it, I get it, but it took me a minute to grok what that meant because I'm like, "It's a video. Of course, it plays in line. What are you talking about?"
By default, on video, on mobile browsers (or at least Safari), when you click a video, the default experience is the screen goes black. Everything wipes away and you only watch the video. That's the default if you do nothing.
If you put plays in line, then you hit play and it's more like desktop. It just fricken' plays the video.
Dave: Yeah. I was in bed late at night and my wife had gone to bed, and a website auto-played a video on me on my phone. [Laughter]
Dave: I was like -- of course, you're like, "Ooh!" You know? You do the panic.
Chris: Yeah. Sorry, babe.
Dave: Sorry. Hey, sorry. Whatever. It always starts with some dumb commercial with a drum track. [Beep bop] Mops! You know? [Laughter]
Dave: It's like, "God dang it, dude!" But then I was actually kind of impressed. I was like, "How did they auto-play the video on my phone?" [Laughter]
Chris: Oh, yeah! You're right. How did they get through those firewalls?
Dave: How tricky. How did you get through there?
Dave: I wish I--
Chris: The one that always gets me is I wanted to listen to one video on Instagram, and then I keep scrolling and Instagram then decides that because you've listened to one video that all videos should have sound on them.
Dave: Oh, yeah, yeah, yeah. Ooh. Wow. What a blessing. Yeah.
Chris: [Laughter] Thanks.
Dave: I only use Instagram on mobile app, the mobile app, and it's funny. The stories format is so bad. Chris--
Chris: Oh, you don't have app installed?
Dave: Yeah, I view it--
Chris: You view it through the browser?
Dave: Yeah, but it's just how I want to operate. I didn't want Facebook on my phone.
Dave: It's such a bad experience. [Laughter] You watch a video -- and this happens on TikTok, the native app, too. You watch a video, and you're like, "Wait. What did they say? Can I rewind it 30 seconds?" No, you have to go through the whole loop, man. You've got to just go around the horn.
Chris: Yeah! I watched a TikTok today, and it's like that, too. It's surprising to me that, yeah, you've got to go around the horn. You cannot just scrub backward.
Dave: I wish I could because there are just times where it's just like, "Wait. What'd they say?" or "What was the goof there?"
Chris: It seems funky because isn't it--? I mean it's still a video. I wonder if you could write a browser extension that forces it on there somehow.
Dave: Yeah. Probably.
Chris: [Laughter] FixTok.
Dave: I wouldn't mind.
Chris: All right. That's cool. So, we talked about HTML a bunch. I would like to force you to talk about Spicy Sections at some point. Do you want to do it now?
Dave: Spicy Sections! Let's get into it. Maybe we do a commercial break.
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by Jetpack. You know on this show, many times I've said, Jetpack is an amazing plugin for your self-hosted WordPress site. It has loads of features. And that is true. There are tons of features in Jetpack.
But I mean more like Jetpack the brand, the product, and less and less (lately) about Jetpack (literally the plugin) because Jetpack has been on this steady march forward by feedback from y'all that it should be split up a bit. I can not only use smaller parts of Jetpack technology and also pay for smaller parts of Jetpack technology.
Rather than it being an all-in-one, you can be like, "I just want to use Jetpack backup," for example. Well, good news. Jetpack backup has been split off not only as a pay-for thing, so you can a la carte just pay for backup if that's all you want. Believe me, it's the best backup for WordPress you can get. You can also now just install a plugin called Jetpack Backup. It's all totally independent.
Just like a lot of the performance features of Jetpack -- very powerful, useful, use them all -- they're split off from Jetpack into Jetpack Boost. That's free. So, if you're just like, "I just want the nice image handling and the critical CSS," just use Jetpack Boost. Pretty cool. Yeah, I don't know.
If you just want to pay for and use and load only the resources that have anything to do with VideoPress, fine. Then just do that. It's cool.
It's cool to see this split apart because that's a big piece of feedback from them was, "I wish I could just use this part and this part." Well, now you can, and Jetpack Backup just dropped as the next one in that. You can both pay for it and only install that plugin if you want. Pretty cool. Thanks for the support, Jetpack.
[Banjo music stops]
Dave: All right. We're back. [Laughter] Okay, Spicy Sections. Where do we begin? Okay.
Chris: Well, this is all yours, but I can tee you up. First of all, you have a blog post about this, which I read every word of because we've talked about it on the show and you really spelled it out. It just deserves a blog post.
Chris: While we're going to do it again, I would recommend that people read the blog post because it's quite good.
My favorite part is when you talk about the history, almost like expectations with tabs. You're like, "Oh, yeah. Tabs, there's a table of contents at the top," which that word is so perfect, right? That means AAAA, you know, tab 1, tab 2, tab 3, or button, button, button, button, button.
Chris: That's fine, but you can kind of (weirdly enough) wipe that from your mind, right? You don't have to build tabs that way.
Dave: Yeah. That's what's interesting. That's what the Why ARIA authoring practices do. That's what, historically, jQuery UI did.
Chris: Every jQuery plugin. [Laughter] Yeah.
Dave: I think that's cool.
Chris: It felt good. Then it got locked in people's minds. That's how all React tabs work these days, and they're generally thought of as what? The three or four HTML elements. You have a wrapper, you have tabs, and you have tab panels. It's at least three.
Dave: Yeah, and then maybe a tab bar would be the four elements.
Chris: Four. Yeah.
Dave: You put all your little tab-O's.
Chris: Because you want to put border bottom on it or something.
Chris: So, you need a wrapper.
Dave: Then maybe somebody might go to a fifth element and do the content panels. Yeah.
Chris: Tab panel wrap.
Dave: Tab panel wrapper.
Dave: For whatever reason. Maybe an overflow or something.
Chris: Yeah. What blows my mind is you're saying that this can maybe be pulled off with one.
Dave: Yeah! And that's kind of what we looked at. The more we looked at it, a one-element solution might serve us better here. It's hard to mouth blog here, but we had to kind of think of the whole problem, like, what do tabs do? They take a tube of content, a long structure of content, and they roll it up to where only one section is visible at a time, right?
Dave: And so, you have a label. Usually, a heading is a good label.
Chris: Right. H3 or whatever.
Dave: H3, H2. That would be your label. We kind of were just like, "Well, maybe we could infer sections of content by the heading structure and then roll it up based on that.
Dave: Yes, and we're doing it in a Web component right now, but maybe HTML could do that. And HTML could figure out, "Oh, this is what they want to present."
But when you start digging into the problem with tabs, you realize, okay, a tab, it shows one panel of content at a time. Right? You have some keyboard bindings that switch the different tabs. j
Guess what else does that. A single column. An accordion that only shows one panel at a time, like an exclusive accordion.
Dave: It's the same thing (from a semantic structure).
Chris: Right because you're saying people do this anyway. You think of tabs as the bar across the top, but a lot of people are like, "Well, if it's a small enough area, a one at a time accordion is actually what a lot of patterns break down to anyway."
Dave: Definitely. Even if you think about something as simple. Maybe it's not tabs to accordion. That collapsing header structure that was really popular -- I think Filament Group had a few blogs on it -- where you had those footer links, and you want to collapse it down to a little collapse on mobile. That was kind of hard to pull off with interactivity and stuff like that, but you could do that on this. It's like, oh, if the viewport is wide enough, just blow those out and open them up.
Chris: Right. You'd grab the H3s, H2s, or whatever, and you yank them up into a horizontal bar (just like you're used to with tabs) if there's enough room.
Chris: Maybe it's an attribute. I don't know how you express it. It looks like, in your Web ..., you express it with a media query or a custom property that has media queries in it.
Dave: Yeah. Yeah, and so this is kind of Brian Kardell's idea is this idea of affordances. An affordance is like a package of an oral and visual experience, like ARIA, the screen reader and the visual presentation changes coupled together. You can change that design affordance, the way it presents itself, using some screen readers or using a few media queries. But we're doing it all in a custom attribute. It's sort of similar to his switch syntax, which was a while back.
Dave: Kind of a container query kind of thing.
Chris: Yeah, this structure is a little unusual here. it's like angle brackets or square brackets with media queries inside of it.
Dave: Yeah, it's very custom.
Chris: Pipes. Yeah.
Dave: That syntax could change.
Chris: It probably won't end up that way.
Dave: Yeah. It 100% probably will change, and so I think this is just sort of the prototype how you might express that. If you just wanted to default the whole -- [laughter] you could change that to whatever you want. If you really want tabs on mobile, you can make it tabs on mobile or whatever. We're just kind of giving a way to show this off.
Dave: Now, through these affordances, that tube of content can be presented in tabs. It can be presented in a collapse pattern. Very recently, the ARIA working group was talking about role equals carrousel, which is kind of like carrousels are terrible, but they were like, "Hey, guess what. They're not going anywhere." [Laughter]
Chris: Hmm. Are you saying this could even possibly help that?
Dave: Well, it might. It might fit into it. The Tabvengers, the group in the open UI I'm a part of, have kind of picked it up to see if it fits in here. We kind of have to dissect carousels and what they mean because there's one at a time carousels, three at a time carousels, responsive-- All kinds.
Chris: I saw some of this. This is probably not going to work. I'm not necessarily suggesting this, and I'm sure you've already thought of it. When it's in the collapsible sections style, they're like details.
Dave: Very much. Yeah. Yeah. Yeah.
Chris: Right? But I don't know if they're one at a time or not. That's interesting to me.
Dave: They're not when it's in the collapse pattern. It can be--
Chris: Yeah. It seems like that's a better default, right?
Chris: Why bother with one at a time in that model?
Dave: Mm-hmm. Yeah. Yeah.
Chris: But maybe it does matter sometimes? I don't know. I was thinking what if you had a group of details, like details set, with the attribute one on it, and that just meant that that group of details could only have one of them open at a time? It just seems like HTML territory.
Dave: No, totally, like a declarative kind of thing, like, "At this point, show this many." You know? I think that's probably what a carousel pattern -- if this ever merged in -- might need to support, too. Like how many visible, how many are you showing? That might even be at a breakpoint, like how many at breakpoint X do you want to show?
That's all complicated. I don't know that CSS even supports language to do that, really. The examples I've been going through are input type. You'd say input type email, and you get some cool email keyboard on mobile.
Dave: Or input type URL, and you get URL validation. Brian Kardell brought up the point of scroll bars. In CSS you can say overflow scroll, and you get a scroll bar. But there's no scroller element in HTML. It's just this affordance that shows up, this UI that shows up when you ask for it, or when whatever heuristic triggers it, like your content on the page is too long.
Chris: Yeah. Interesting. All right. Well, read the blog post, people. I wonder. Spicy Sections is unique. It's Googleable. It's all that. But what is really going to be?
Dave: Probably not tabs. I think a lot of people have come up with different names. I actually don't care. [Laughter] I care about the outcome more than the name.
Chris: Maybe it's just an attribute on the section.
Dave: Yeah. Sections plural - or something.
Dave: I don't know, but there's this idea of content set or panel set or Hixxy (in 2004) called it Tab Box, which is fine. I don't know. But there's probably an infinite number of things of what it could be called.
The positive note is we've got some really good, positive signals from people who work on browsers. I know Nicole Sullivan is very excited about this. She was at Google and very influential, in my opinion. And so, the outlook looks good. But what I would say now is please, please have a play with it because we need feedback. We're at the "we need feedback" stage. Please. Because if it does not help you or if there's a major fatal flaw, we could be in trouble. [Laughter] Or we have to redo something, like we have to go back to the drawing board.
You could even see -- I don't know if this will make the cut or V1 or whatever -- from a screen reader perspective. I don't know. If you have limited mobility, you're like, "Never show me the full tube of content. I would rather opt into stuff," or "Never show me tabs because I hate those." You know? Stuff like that. There might be media queries prefers no tabs or whatever. [Laughter]
Dave: Or prefers affordance tabs or something. I don't know. I don't know if any of that will happen, but it's just something to consider. Maybe there's some user control that we could offer, too. Prefers carousel - nope. You know? [Laughter]
Dave: What if that's in HTML, Chris? Awesome! You know what I mean?
Dave: That would change everything. That would change - I don't know - HTML slide decks and stuff. That would be....
Chris: That's cool. I don't blame you for getting involved. Now it's feeling like a little more fleshed out and you're almost past the research phase, it's getting more exciting, right?
Dave: It's getting exciting because, right now, we have research, we have documentation, we have a candidate, and a Web component, so you can play with it. It's not this theoretical "one day, the browser might ship - whatever - input type face detection - or whatever." It's not this theoretical. It's a very workable prototype, so I think that is exciting. And so, we can get feedback, and we should get feedback. Then it'll move on to the working groups, hopefully, if open UI is thumbs-up, and then it would -- yeah.
But I would love to know. Is the tab or the heading content structure, is that a dealbreaker for you? Is that interesting to you, or is that a yep/nope?
Chris: One more time. The tab structure?
Dave: It says H2 tab heading 1 content.
Dave: Is that a dealbreaker for you, or is that interesting to you?
Chris: I like it. I'd prefer it. I think it makes more sense, but it's a little mental twisty, and then what really is it? It's not going to be H1, H2, H3, or H4. How am I going to tell you which thing should be the tab?
Dave: It kind of auto-infers. Yeah.
Chris: Maybe it doesn't matter.
Chris: Oh, it auto-infers.
Dave: Then it's sort of like detail summary in that way, so it would kind of be like your H2 is your summary element - sort of. Then it kind of auto-parses it. If it fails, it just chucks it at the bottom; chucks the stuff it couldn't do at the bottom, sort of like how HTML is good at failing.
Chris: Well, that's interesting. That's actually better, I guess. It feels HTML-y to guess. You know?
Dave: Mm-hmm. Mm-hmm.
Chris: But it'll have to be some algorithm. There'll have to be some canonical blog post about it. I'll raise my hand to be that resource, probably.
Dave: No, I think it's--
Chris: But what's it going to pick? What if there is an H3 first and then an H2? Which one is it going to take? That kind of weird stuff.
Dave: See. Yeah, I don't know. I mean I think it would try to keep the heading level structure because it's saying, "Oh, he started headings or he started tabs at H3, so he must want it at this level."
Dave: But if you chucked in an H2, it might, in its current state, decide to just help you out [laughter] - or whatever.
Dave: But I don't know. I don't know if it locks you into a thing. But yeah, now we're messing with the document outline, and that's one concern I have is we're sort of touching the document outline. Does that mess with people? Is that good thing or a bad thing?
Dave: Well, and that's sort of what we're coming down to is, if you really want that, you can write your own. [Laughter] I mean that's what we've been doing for decades.
Chris: Yeah, right. You don't solve everything under the sun.
Chris: You can't. There have got to be some tradeoffs.
Chris: What's the tab order, then? If you're in a situation where it's visually presenting that way, that's the tab order anyway, isn't it, a little tab across the top?
Dave: Yep. Yeah, it'll just shoot across the top.
Chris: Yeah. That's awesome! You had to write nothing to make that work? That's fricken' great.
Dave: You just had to wrap it in Spicy Sections.
Dave: Then it works for you.
Dave: Yeah, yeah, yeah.
Dave: Just to troll me.
Chris: Just to rain on your day.
Dave: Just fricken', like--
Chris: Yeah. [Laughter]
Dave: You have to - whatever - do window.enable-tabs.whatever. Yeah.
Dave: Just to -- yeah.
Dave: My headstone says--
Dave: "Damn it!"
Chris: Yeah. Yeah. [Laughter] HTML dead ports.
Dave: Yeah. Anyway -- [laughter] Oh--
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by Shortcut. Have you ever been really happy with your project management tool? Most of them out there are either too simple for a growing engineering team or too complex for anyone to really want to use.
Shortcut, formally Clubhouse, by the way -- name change -- is different. It's built specifically for software teams. It's fast, intuitive, flexible, powerful, and many other nice, positive adjectives - happy. Shortcut features include team-based workflows, org-wide goals and roadmaps, tight VCS integrations, keyboard-friendly interface, integrations planning.
Sign up at shortcut.com/shoptalk. What a nice URL, shortcut.com/shoptalk. Get two months free. Very generous of them. Thank you. You shouldn't have to project manage your project management.
[Banjo music stops]
Chris: You know one of the advantages to having a podcast is, if you complain about a feature, it tends to get some attention once in a while. I don't know how this even came up again, but I mentioned Cloudinary and how I have this weird problem with the way back machine and how, every time the way back machine indexes my site, it prefixes all of the IMG elements SRC attribute with cdn.waybackmachine.com dot blah-blah-blah.
Dave: .cloudinary.whatever. Yeah.
Chris: Well, yeah, so it's got that URL, then the Cloudinary fetch URL, then my image, so every Cloudinary is fetching new versions of every single image.
Dave: Yeah, for way back. Yeah.
Chris: All the time, which means there are hundreds of thousands of fricken' images in my Cloudinary account that are just repeats. It's not necessary that they're there.
Chris: The reason for that is it's like neither company's fault, really. It's just weird how it pans out. There was a good solution for it from Cloudinary, so high-five to both Eric Portis and -- I'm going to do this right because it matters -- Irwin Lucas (who works for Cloudinary) really went the extra mile to explain to me every detail of how this works and yadda-yadda-yadda.
Chris: They have -- you are familiar with the fetch API a little bit, at least in theory. Right?
Dave: Oh, yeah. Yeah.
Chris: Yeah. They have an alternate version of the fetch API that does not require -- for whatever magical reason -- that you put the full URL of the resource you're fetching at the end of it, like with the http://.
Chris: Yeah, they have another feature that's kind of better that's called Auto Upload. It just requires a little bit more setup, so it's not as generally useful as fetch, maybe. But if you use it, it's called the auto-upload feature. It means it still grabs that asset from elsewhere, but then it puts it in your Cloudinary account. Then you can mess with it in your Cloudinary account and, when you mess with it, those changes persist.
Chris: It just is a little different URL structure. You've got to make a little bucket for them, so it goes into the right bucket and stuff.
Chris: It's kind of interesting. But it ultimately works the same way, similarly easy to use, and then because there's not that extra https in the middle of the URL, it totally solved the way back machine problem. It just kind of was double-duty.
Chris: They sorted me out, and pretty cool.
Dave: It was like your Cloudinary was filling up with these garbage way back--
Dave: Whatever URL generations.
Chris: Loads of them.
Dave: Question mark from this year, from this year. Yeah.
Chris: Yeah, and it's not like it costed me all that money, but it made, for example, the media library on Cloudinary useless to look at it because it's just all repeats. Yeah, it's totally fixed, 100%.
Dave: So, is it fixed now? Is it all merged down? So, all these auto images kind of go in their own little world, sort of? Is that kind of it?
Chris: Yeah, they do. But it's still useful. I can browse it. There are no repeats. Yeah, they're kind of isolated and all that.
Dave: See! This is why you have a podcast, so you can complain and then people fix or explain your problem.
Chris: Yeah, and it wasn't even a big deal before because it didn't really cost that much money or problems or anything. It just was weird and kind of a waste of electricity, frankly.
Dave: Yeah. Yeah.
Chris: The other thing we did is, after we got it all working, they have this bulk request delete form, essentially. You say, "Delete all assets older than this date in this bucket," that kind of crap, and I just filled it out and mass deleted all those old duplicates. Done.
Dave: Dang. Sweet! That's cool.
Chris: Thanks, Cloudinary. Not a sponsor. Could be.
Dave: And if there are any, like you accidentally deleted any image, it would just regenerate, that you are using currently.
Dave: That's awesome. I need to -- yeah, I need to use Cloudinary.
Chris: Yeah. Look it up. They've got a page that says, "The difference between," or "Comparing fetch to auto-upload," and it really clearly lays out that they're very similar APIs, but basically auto-upload is cooler. [Laughter]
Dave: Wow. I'm going to look it up.
Chris: So, anyway, Apple, I have a problem. I need three pro display XDR monitors.
Dave: Okay. You supply chained?
Chris: Because I want to test it out.
Dave: You supply chained?
Chris: Yeah. No, I'm just saying, "Ship them over to me, and then I'll mention it on the podcast."
Dave: See. Okay. Yeah.
Dave: Apple, we have a major problem. [Laughter] Actually, Apple, if you want to send me a new computer--
Dave: --so I can use my computer with more than one monitor, that would be awesome. [Laughter] That would be--
Dave: What else can Apple do for us? You ended up getting a new Mac, huh? This is now a Mac podcast. If you want to fast-forward in your podcatcher, you can just hit the next chapter button.
Chris: No, I mean yes, I did, but I did unapologetically because I have a 2018. It's almost 2022 now, so almost 4 years out of that beast because it was like January 2018, or something.
Chris: Whatever. It served me well, and I'm ready. Our company is ready for the ARM architecture, and I'm a fricken' fanboy anyway. I make all of my money sitting in front of a computer, gosh darn it, and I have this side project podcast that could buy me the thing, but I didn't even need to because it's a business expense and it means I don't pay taxes on the money that the podcast costs me. And you're God-dang right I'm going to get it.
Dave: Cha-ching, cha-ching, cha-ching. Well, it amortizes over five years. [Laughter]
Chris: [Laughter] Sure. Yeah, because you can't have October 2021 looking terrible on the books just because you bought a bunch of computers.
Chris: You've got to amortize that. Stretch it out a little bit.
Dave: Stretch it out. Five years.
Chris: Well, we do all that stuff, of course. Yeah. No, I'm stoked for it. I got everything. I turned up every damn dial on that thing. I just want to feel it.
You know what I won't? I hate to say this. It's not even here yet. I'm going to love it. I'm excited about the machine. I'm an Apple fanboy and all that. But Web work just is not that--
Dave: Memory intensive? Yeah.
Chris: Your Webpack isn't going to go any faster, I'm afraid.
Dave: Well, so that's what I would love to know because it's like, "Ooh, more cores! Aw, dude! 72 GPU cores." You know?
Dave: I wonder how multithreaded Web development is. You know what I mean?
Chris: None. Zero. None.
Dave: Zero multithreaded, so.
Chris: As far as I know.
Dave: Yeah. Yeah, yeah. Because I saw somebody post, like, "Single-core performance is about the same," but it's the multicore performance that are in all those charts and graphs that they're talking about.
Chris: Right. This computer -- and all of this crap, even the Pro XDR monitor and all that -- it's for video people.
Chris: Your life is sweet right now if you are rocking those beautiful screens that support 50 billion colors per pixel - or whatever.
Dave: Right. Right.
Chris: But I do video editing. ShopTalk Show video is edited by me.
Dave: Like and subscribe.
Chris: Not that I do that good of a job but, in fact, we should probably talk about that at some point.
Dave: Yeah. [Laughter]
Chris: Somebody else probably should take over on that job, but I do export a lot of video. That really will cook, but that's going to go fast.
Dave: Well, and I think I was talking to somebody who does audio. I think even your audio cuts go so much faster. Just - pew - one-minute podcast exports and stuff like that.
Chris: Yeah. I think that I'm actually going to feel that. I like the RAM and all that stuff. I like to not -- I feel like I spend most of my life on computers really thinking about what's open. Constantly like, "Oh, I better quit Photoshop before I start my browser," or something.
Dave: Yeah. Yeah.
Chris: Not super lately, and I feel like that's been nice lately that I don't care. I could be halfway through a video edit and just minimize the video thing and just move on with something else. That something else could be Photoshop.
Chris: Then I also have 50 tabs open, and I'm running Notion. I've got all kinds of crap open and I never think about it.
Chris: Once in a while, just through idle muscle memory, I go quit some apps or something. But for the most part, I do not think about it.
Dave: No, I mean that's very compelling. Actually, I took a foray into Docker. I'm getting into Docker. I feel like everyone should know that.
Chris: Oh, my god. Yes, please.
Chris: Docker on my M1 is slow. It's very slow. But I'm sure I just don't have the dials turned up or whatever. I don't have enough dynos in my Docker.
Chris: Not to distract you too terribly, but you were making it work and all that. There are dials right in the UI where it's like, "How much memory should it have?"
Chris: "How much CPU should it have?" And you've really got to get it right because either direction is bad. If the Docker doesn't have enough, that's bad. But if you give it too much, that's bad too.
Dave: It chokes my whole system, yeah, and so I need to figure out what that magic spot is. You know even just NPM install is like, "Okay, bud. I'll come back."
Chris: [Laughter] Really? Yeah.
Dave: Yeah, but I think there's also another flag. Docker is great, but it's so opaque to me because the education is all just like, "Oh, man. You want to set up a Kubernetes triple flop stack with load balance blarpy-bleep?" I'm like, "Dude, I really just want to run a Node app." [Laughter] I want to put Nuxt to a container and deploy it as many times as I want (50 times).
Well, it's more like I'm building a thing, and if somebody is like, "Hey, I want that thing. I want to pay you for that thing," I want to be like, "Cool. Here it is. I stood it up for you. Let's just put your content in."
Dave: That's the goal is I just want to lower the cost or time to install, I guess. That's the metric I'm trying to optimize.
Chris: I think that's great because it probably will run way faster on your native machine. But then you're selling it to somebody who is on Linux or whatever and it doesn't install for them. You've just neutered your week of your time. Whereas, if it's a Docker, it really will work on their machine.
Dave: Yeah. Yeah, well, hopefully, right? And so, the issue I've been having is--
Dave: --we get to this point and it's like, "Container as deployment resolved servers." You know? Then Apple shows up. "Doot-doot-doot. Guess what, buds. I'm changing the whole fricken' CPU. Talk to you later. I don't talk to anybody. I'm out." [Laughter] You know?
Dave: Now we have this Docker file, which is great. We figured it out. But the Docker file has to inspect the architecture to make one little Rust doo-dad, like install the right binary and find the right binary. Then you have to--
Dave: It's fine, but it took two weeks of debugging and just Docker up, Docker down, Docker up, Docker down. You know?
Chris: Hmm. Yeah, the feedback loop for testing it is real slow.
Dave: Oh, yeah. It couldn't be slower because you're just like, "Okay. Let's try it again in 300 seconds." I probably should have (while in that testing phase) juiced it, just given it all the juice it needs.
Dave: I was pretty -- I don't know.
Chris: It reminded me of that e-book work I did. Make one little change. Run the command line to build it. Two minutes later, look at the result. Uh-oh. Not right.
Dave: That used to be kind of Web development. You'd make a change. You'd FTP it up. You'd wait about two minutes.
Dave: Hard refresh. Oh! I wiped out the site.
Dave: [Laughter] We're so used to HMR and--
Chris: Right. You're told within half a millisecond if you typed the wrong thing.
Dave: If it's over half a millisecond, I'm like, "What's wrong?" [Laughter]
Chris: Right. That's why I shiver when people say, "Oh, my Webpack takes 90 seconds." You're like, "What?!"
Dave: In the D-d-d-d-discord, people are like, "Dude, is GitHub down?" It was because requests were taking over a second. You know? [Laughter]
Dave: Is GitHub entirely down?
Chris: Yeah. Expectations change a bunch.
Dave: Yeah, so it's very much -- I don't know. This Docker thing, it's been an educational route, and I generally understand this stuff. For me, I get hooked up on jargon, like, "Okay. Docker, how do you want me to do this? I know how to install an Ubuntu server, but how do you want me to do this?" You know?
Then, "Okay. Why didn't that work, Docker? Now I have to find out why you didn't like that." You know?
It's all this install Google, install fail Google loop. You know? Fix it. There's a problem. Okay. Google it. Try something else.
I'm just copy and pasting commands right now and it doesn't feel like I'm super skilled yet, so I'm in this novice phase and it's kind of frustrating. But I'll get through it. I wish there was a good--
If anyone has recommendations for a really good "How to become a fricken' sick Docker master"--
Chris: Docker master?
Dave: Dock master [laughter] because that's an actual job title, right?
Chris: The people who are really good at it are the industry leaders in it, I feel like. We tried to hire one at one point. I was like, "Whoa! Your salary is crazy. Bye."
Dave: Like Kelsey Hightower?
Chris: [Laughter] It was in that ballpark.
Dave: I don't want to hire a Kelsey Hightower. Anyway--
Chris: Because everybody's architecture is like that, especially if you're at scale. If you're at scale, you're making money. Whatever. It's a good job. Kids out there, that's what you should do. Do dev-ops.
Dave: It's such a specialty. You know? I think if you have a knack for it, fricken' do it. Just be a dev-ops person, and you help people solve their internal problems all the time. That's so cool.
Chris: I fanaticize about it. You know? It's in that same type of fantasy where I'm like, "I should go back and get a Ph.D. in math."
Dave: Oh, is that your--?
Chris: I'm not going to do it, but I want to. That'd be neat.
Dave: Is that your grad school fantasy, a Ph.D. in math?
Chris: A little bit. I think that's my best one. Maybe music, too, but I feel like there are so many naturally talented people at music, it scares me. Whereas math, I feel like I could brute force my way into it. But mostly, my fantasy is being on a college campus again.
Dave: Oh, hacky sack.
Chris: Sitting around the quad, talking with--
Chris: Yeah. But I don't care about hacky sack, but I care about intellectual conversations just for the sake of it.
Dave: Sure. Sure. Sure.
Chris: Nobody is really giving a crap about money or their jobs or anything. They just want to solve a proof.
Dave: No, that's perfectly admirable. Mine is way more selfish. I want to get an MBA so I could walk into a meeting where I'd meet business people, and I'm like, "I am a developer, but I'm actually on y'all's level, so get ready. We're going to talk about Excel. Okay, man. Check it."
Dave: Merge sort. I don't know.
Chris: There are real skills that you gather from MBA.
Dave: I think so. I think I would. I may still do it because I have a friend who did a night school MBA.
Dave: It almost killed him, but it was pretty great.
Chris: I do selfishly kind of want to get to that level of -- this is bougie crap -- I've been working hard for a long time, Dave. Can we just strike it rich at some point? Then life opens up to this--
Dave: Oh, yeah.
Chris: Every decision I make isn't definitely -- you know because right now all my decision-making is, "I still need to make X money to make sure that this family works," and it's a very pressure-based thing.
Dave: Yeah. Yeah. Yeah.
Chris: Like everybody else on Earth, I have to work to make money to pay for the things.
Dave: Well, and then there's -- [laughter] -- I think, for so much of my life, Paravel has done very well over the years.
Dave: But it's funny because it's so inconsistent. There are high months. There are low months, high years, low years. But I think my posture is always like, "Paravel is going out of business next week, so make sure--" You know? But it's never, but it's always in--
Chris: Yeah. That's like a Jeff Bezos thing. "Live your life scared as hell."
Chris: He has some quote like that. [Laughter]
Dave: I don't know. It's just this idea of, like, "Okay. Do you have the backup plan if the bottom falls out?" Not like I'm a huge prepper, although I have bought some prepper magazines (if you've listened to episodes of the podcast in the past).
Dave: I'm not some huge prepper, but it's just like, "Okay. If the money well runs out, what do you do? Then when do you call it?" Anyway, we're all fine. Don't worry about us. But it was just that background fear of, like, "Dude, what do you do?"
Chris: I think you go work at some weird enterprise auth company or something that nobody has really heard of but somehow makes millions of billions of dollars.
Chris: Just be a little dev dude. Do your Jiras.
Dave: Do your Jiras. Sit down and do Jiras. Pushback always. That's it.
Dave: "You need what by when? Hmm. I can do half. That's it."
Chris: [Laughter] Half that, then half that.
Dave: Double half that.
Chris: You know we did a video on Cloudflare?
Dave: Mm-hmm. Yeah.
Chris: Workers. The first thing I did was, like, "Oh, see how this default worker, I can just type DaveRupert.com in there? Then it does a fetch for DaveRupert.com and returns that website."
Dave: Yeah, it was awesome.
Chris: Yeah. That's compelling right away because you're like, "Oh, weird." You know? [Laughter] Now there are two DaveRupert.com just because I typed in a URL.
Chris: But imagine -- so, that's just a one-trip thing. Then we talked about, oh, well, obviously this thing could perform multiple fetches, stitch things together, and all that. One interesting thing that it can do that I think -- I wonder if we'll see more and more of this. I'm actively doing it as a test.
Chris: When you embed a Pen, it links to a library that we host for you on a CDN that's called, like, ei.js or something weird we call it.
Chris: Embedded. I don't even remember what EI stands for. Wow! I'm terrible.
Dave: Embedded integron.
Chris: Meaning that nobody is going to block it.
Dave: Hmm. Dude! You just solved malicious ads. Good job, Chris. [Laughter]
I'm doing it now with analytics. I read this blog post from Plausible that was--
Dave: Oh, my god! Hold on. Okay. Yeah. Keep going. Sorry. Because I have an issue on my site. I get an accessibility error from my Carbon Ads. Love Carbon Ads.
Or it's like a performance error because it's like, "Oh, you did a bad TTL (lifespan of the image or whatever).
Chris: Oh! Yeah, you could adjust the header, so it's a proxy but it's a proxy that messes with the headers to hold onto it longer.
Dave: Yeah, and then it comes back with a slightly large image.
Dave: I could just pass it through.
Chris: You could bonk it through the resizer, too. Workers can do that.
I'll say that it was a little clickbait-y of an article from Plausible IO, but I don't blame them. That's their job in life. The title of the article is "58% of Hacker News, Reddit, and Tech Savvy audiences block Google Analytics."
That's a click for me because I'm like, "58%?! Really?!" Not like I get most of my traffic from Hacker News and Reddit, but CSS-Tricks is a Tech Savvy audience.
Chris: My analytics information is Google Analytics. I've had it on there since day one.
Dave: Yeah. Yeah.
Chris: It appeals to me to have that long of a data set of traffic information.
Chris: But I'm like, "58%?! Wow!" That's high. Meaning that if all those people didn't block analytics, your analytics would look about double or more what it does now.
Dave: You've got to turn it on, dude. You've got to first-party it and see what happens.
Dave: Okay. Yeah, yeah, yeah.
Chris: In fact, they do nothing. It's very privacy-focused analytics anyway. So, nobody is rushing to block it anyway because they do a good job. Right?
Dave: Yeah, header.
Dave: I'd love to know the percent, though.
Chris: I bet it's like 10%.
Dave: Okay. Okay.
Chris: For me. For me.
Chris: But I haven't run the numbers exactly yet.
Dave: That could be just on Plausible. I bet GA is a bigger surface area. I bet more people block GA.
Chris: Oh, absolutely. The other problem is that we don't know their exact methods internally for counting these numbers. It is different code. Just because Google Analytics says, "You got 28,000 unique visitors," and Plausible says, "You got 29,000 unique visitors," it's not the same codebase counting that stuff.
Chris: They have to do fancy crap. They're both filtering bots because who cares how many bots hit your website. That doesn't matter. What if they count bots differently, is the point.
Dave: I have two sets of analytics. Ooh, Blogtober is kicking off here, dude. Blogtober is happening.
I have the server-side and the client-side. I have Fathom, which is another privacy-focused, self-hosty.
Chris: Oh, yeah. Nice.
Dave: I did the self-hosted route. I think the product is way better if you pay $15 a month for it. But you know I've got 14,000 page visitors in the last 4 weeks on that one, and 20,000 page views. Pretty good.
Dave: But then on Netlify -- let me go to Netlify.
Chris: Oh, you flipped that on, too.
Dave: I have that going because that's server-side, so that's like zero penalty.
Chris: Zero penalty, but they also don't filter bots, so it will just look--
Dave: They don't filter bots, so they have me at 334,000 page views.
Chris: Oh, my god.
Dave: So, one order of magnitude higher, plus.
Dave: 1.5 orders of magnitude, and then total unique visitors is 27K, which is about double the 14K. It's really interesting.
Dave: Yeah, because--
Chris: Oh, cool.
Dave: Then it saves to my own DigitalOcean.
Chris: Yeah, so nobody is blocking it.
Dave: It should not be blocked.
Chris: An order of magnitude difference, though, is whack. They're both useful for relative, like if you see a spike, a spike is a spike. The spike is there for a reason.
Dave: A spike is a spike.
Chris: If you're comparing them across analytics tools, pfft, what the hell are you supposed to think?
Dave: Mm-hmm. Yeah, I don't know what to do. Then there is all this traffic from Germany. I think I'm on some weird botnet in Germany because of 107,000 page views from Germany.
Yeah, and my top posts are all old posts or offline or something, so I don't even know, man. Let's see. Yeah. The traffic to my blog posts is double on Netlify than what it's reporting in Fathom. Not saying Fathom is wrong. Their new paid product is maybe better than this unsupported self-hosted one, but it's really hard to know how many people actually go to your website. That's all I'm saying. [Laughter]
I wish people knew. I wish you could know that. I don't super care, but I wish you could know that. I wish there was not just a giant question mark in the sky.
Chris: Yeah. I'm sure many people disagree, but my guess is that your best bet is Google Analytics because they have played the game for so long that they're just an entrenched player in that.
Chris: Especially if you proxy it. You can even run Google Analytics server-side, believe it or not.
Dave: Yeah. Yeah. I hear that's what people are shifting to because I think stuff is blocking it. I think we've done tracked too much and everyone is kind of getting sensitive and blocking it.
Chris: Yeah. Yeah. Even I mostly block it. I'm not actually worried about the performance because the scripts I know are written to not be that bad, and they are deferred always. The default snippet is pretty chill, and I'm not that worried about the perf, but it is doing some work.
Chris: My CPU is doing some stuff that's irrelevant to me, so why would I let it do that?
Dave: You can see.
Chris: It's my computer.
Dave: If you watch it. I think this came up recently in the D-d-d-d-discord as well. If you run a perf trace on it, you see the yellow slug of slowness, it'll block the main thread, just Google Analytics.
Chris: Oh, it will, occasionally? Oh, well. There you go. It does something.
Dave: Perhaps Google tag manager, specifically. Yeah, it's just like, "Well, that sucks." [Laughter]
Dave: Google is telling me to be fast, but then you install their analytics, and then it's like, "Ah, see. You're not fast anymore."
Let's wrap it up.
Chris: Let's do this again some time.
Dave: Yeah, we should do it again.
Dave: Yeah, pretty soon because I have to go out of town. Thanks, dear listener, for downloading this in your podcatcher of choice. Be sure to star, heart, favorite it up. That's how people find out about the show. Follow us on Twitter, @ShopTalkShow, for 16 tweets a month.
Join us on the D-d-d-d-discord, patreon.com/shoptalkshow. We've got a YouTube over on the real CSS-Tricks YouTube channel. Be sure to like and subscribe.
Chris: Heck yeah, we do.
Dave: Chris, do you got anything else you'd like to say?
Chris: Oh, ShopTalkShow.com.