425: Tailwind, Where to Find Inspiration, SVG Corrections, and Web Workers

Download MP3

We're talking about health, Tailwind CSS, getting overwhelmed with where to start on a project, some follow up on SVG sizes and web components, and why isn't there a bigger focus on web workers?



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

Chris Coyier and Dave Rupert

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

Time Jump Links

  • 01:18 Health in the front end and back end
  • 04:01 What are your thoughts on Tailwind CSS?
  • 20:43 Sponsor: Wireframe
  • 22:26 Getting overwhelmed by building websites
  • 32:32 Sponsor: Framer
  • 34:14 Correction: Big SVGs
  • 35:34 Web component follow up
  • 42:02 Why isn't there a bigger focus on using Web Workers?


[Banjo music]

MANTRA: Just Build Websites!

Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another episode of the ShopTalk Show. I'm Dave--overweight and overaged--Rupert and with me is Chris--the one who never misses--Coyier.

Chris Coyier: [laughter]

Dave: How are you, Chris?

Chris: Good. Good. Good. Good.

Dave: Oh, good.

Chris: I'm afraid that you've shipped your back problems over to me. My god.

Dave: Oh, really? I'm sorry.


Chris: No, it's not bad. It's a little stiff down there. Then I go to the gym because I'm like, "Yeah, you know what it takes to be healthier? You know you eat right and you go to the gym and then you're healthier." You know?

Dave: Mm-hmm.

Chris: Lately I've been like, every time I go to the gym I'm like, "Oh, my back!" And every time I don't go to the gym I'm like, "Ah, I feel good. Limber." [Laughter]

Dave: When I was having back problems and sharing it on Twitter, of course, because that's what I do--why would you share your personal health on Twitter, but I do--you know, people were like, "Hey, you should come deadlift with me." I just was like, "Duck no!"


Dave: No. That sounds the opposite of what I want to do. I know I probably need to do that to, like, strengthen my whatever.

Chris: Oh, yeah. There's truth on both sides.

Dave: My back and stuff, but--

Chris: While you're in pain, no, but after you've kind of chilled it out and to strengthen it, sure, you know. I think there's a little bit of, like, counterintuitive too that I think some of your, like, chest and core and front side stuff are what's necessary to strengthen to reduce the load on your back.

Dave: Yeah. Yeah, it's the, like, how do I fix my back? Uh, I don't know. Sit-ups is probably the answer. You know, it's guts or whatever.

Chris: Yeah. It's like, how do you fix your front-end? Fix your back-end. You know?

Dave: Yeah.

Chris: How do you fix your back-end? Fix your front-end. Yell at each other.

Dave: Have less stuff. [Laughter] That's it.

Chris: Less stuff. There you go. There is a -- yeah. I like it.

Dave: But what I don't like -- so, we've talked about health stuff here. What I don't like about the health, the health industrial complex, I'm going to call it, is it's like, "Oh, hey, Dave. You want to be healthy?" Yeah, I want to be healthy, health industrial complex. "Yeah, you've got to starve yourself, man."

Chris: [Laughter]

Dave: "You've just got to eat peanuts for the next eight weeks." It's like, that doesn't sound fun, health industrial complex. Why would I--? I have to hurt myself to, like, get healthy? "Yeah, you have to hurt yourself. And then lift these big weights and they'll tear your muscles, but then your body uses the energy to rebuild those muscles. And that's how you get healthy, Dave. You injury yourself."

I'm just -- that sounds terrible. [Laughter] Why does getting healthy require so much self-injury? I don't get it. I don't like it.

Chris: [Laughter]

Dave: I won't do it. I don't know.

Chris: I feel ya. I feel ya. There's -- everybody has got an answer to this, though. You know? I remember when I used to go to fat camp more. I still miss it, but not with a family. It's harder to go.

They had this concept called, like, volumetrics or something. I think that's what it was called. The idea was that you're eating this big pile of food. It feels like a huge meal but you've designed it such that it's still -- you might as well be eating peanuts, you know.

Dave: Yeah.

Chris: It's just lots of greens and stuff in there. It was kind of a cool concept but pulling it off is harder than it looks.

Dave: Well, and you can have spinach for about five days and then you're like, that was enough spinach for quite possibly the year. That was enough.

Chris: Yeah.

Dave: It's good. I like spinach. I like greens, collards and kale, but about five days of that. Woo, buddy. That was good. I don't need that anymore. Next quarter.


Chris: Let's talk about, um, here's a good one from Daniel Hughes, Hughis, or something. "What are your thoughts on Tailwind CSS? Previously, I've been using Bootstrap for many years but since switching to Tailwind about a year ago, the time to build our front-end based on a design comp has become considerably quicker. You build strong muscle memory for the class names and the plugin system is great. Bonus that the CSS class names are purged, heavily reducing the CSS file size. I'd love to hear your guys take on this."

I think you described it pretty well, Daniel. If people haven't heard of Tailwind, it comes in that, I guess, Atomic CSS function or functional classes. You put class name, literally, class names on every single element and they're kind of single-use, so you're just, through a class name, describing the color. Then a different class name, you're describing the padding. In a different class name, you're describing the width or something or the fact that it's a flex parent. Then there are yet more classes for how, if you want that to only apply at a particular breakpoint.

When you're looking at a Tailwind codebase or whatever, whatever you want to call it, each element has kind of a lot of classes on it, you know, like a lot, a lot. You know? Like tens, dozens, you know. It's just kind of the nature of the beast.

Dave: Per element, like you go down the tree of things.

Chris: Right. Right. Right. Right.

Dave: Everything has a minimum of probably five classes….

Chris: Sure. If you -- I don't know. If you've been around -- that's just it. If you've never seen that and you've never worked in that way, I think the required initial reaction to that is, like, disgust, you know, especially if you've heard the advice of your where it was like, you know, don't do that. That's bloat. That's the combination of styling and semantics that we've tried to avoid for so long and Tailwind kind of reinvents.

I shouldn't just say Tailwind because this has been a movement for years now. There's just a lot of developers that really like this way to work. I want to say, upfront, I literally don't care how you build a website. I like to be helpful. I like to talk about building websites. I like to talk about tradeoffs.

All that stuff is so fun to me but, fundamentally, I don't care how you do it individually. I just don't. You can do whatever the hell you want, especially if you're productive and happy doing it. I see so many people using Tailwind who are productive and happy doing it. I just want to make that clear. I'm the last person to rain on your parade of loving this.

I have tried it. I tried to do my personal blog using it. I don't have the muscle memory yet and it just wasn't doing it for me. One reason for that is that I kind of like this concept of, like, CSS injection. You write some CSS and you hit save and then something puts it on the page that doesn't require a page reload. It just feels fast. You get that with Tailwind if you're in a situation like you're using hot module reloading, like you're using Vue or React or one of these frameworks where that comes along for the ride because of the tooling that you're using, that you would get that but you normally don't get that when you change HTML.

When you change HTML on a page, you can't live inject that normally, so you're in this thing where now you're writing Tailwind but the whole page is refreshing because my site is just like a WordPress site or something. So, I think you need some friends with Tailwind to make it palatable, in a way, and that you're already using a friend because you wouldn't want to ship all of Tailwind.

The point is that you kind of -- I think it's a little confused because some people are like, "All these Tailwind sites look the same." Yeah, I guess if you use it off the shelf, but they try to encourage you to customize it. It's a configurable product. Those class names that you apply to things, they don't say padding 20 pixels. They say padding medium, and you can configure what padding medium means to your site.

Dave: Mm-hmm.

Chris: It's all very configurable. The fact that they all look the same, it's like, eh, you're just using it off the shelf and I guess that's why. They also have this thing called Tailwind UI, which is like a prebuilt componentry that has all the classes on it already. I suppose if you use that off the shelf, again, things will look very much the same. I get why this is kind of confusing to people. It's a little confusing to me, honestly.

Dave: Yeah. I think you summed it up. You described the landscape really well. It's a great project. If you do, like you're saying, feel productive, that's awesome.

I'm actually working on a Tailwind project right now, so I can't talk specifics because it's client stuff, but I can talk about utility CSS, in general. I like a handful of utilities, like spacing and padding or heading sizes and stuff like that. I like some utilities in my CSS library. But I don't know that I'm 100% gung-ho about the -- we're doing everything in utilities. That's maybe my old brain, but I think, specifically, if you want to change the behavior of a component or extend or something like a theme or something like that, in Tailwind you have to go through and write, rewrite all the classes, or maybe you did some sophisticated configuration or something.

You have to go through, like, I want dark theme. Oh, okay, I applied dark theme. But then I got to go and make all my text white. You know? I've got to go through every single element and make the text white or, I guess, figure out where in the cascade I can make all the text white.

Again, not the end of the world but, for me, it puts a lot of weight on the templating, on the HTML. You have to start putting if statements and stuff in there to start making the templates, especially in a CMS where you click a button or something like that. You're putting a lot of weight on the CMS or on the templating just to do this wherein regular CSS, I could just say--whatever--my component dash dark and I can use the cascade to write overrides. Maybe that dark is only a few lines of code or something like that. For me, that's a little bit easier than making my templates a little more complicated, if that makes sense.

Chris: Mm-hmm. You've said in the past that this kind of thing is -- if you're styling something, the complexity lives somewhere.

Dave: Mm-hmm.

Chris: It just does. So, to pick it up and move it from one place to another place doesn't remove the complexity. It just moves where it lives. I don't think -- there is no styling solution that just removes complexity. I can't tell you, if you use Tailwind then styling is easier. It's just different.

Dave: You may be dodging some complexity because you didn't have to write any CSS and that was awesome. But now you have to write all the HTML classes. For me, it makes it a little harder to work. If you're working in components, maybe it's less hard because you're like, I only care about this component right now. Maybe it's not actually harder, but sometimes when I jump into a file that has a bunch of classes, I'm a little overwhelmed. I'm just like, what is going on here?

Chris: Mm-hmm.

Dave: You know? There's a little bit of divide. I don't want to, like -- that's maybe splitting hairs, but just to get something to style correctly, you might need to chuck an extra div in there or something.


Chris: Mm-hmm. Another thing I've heard people say is that, you know, like Daniel said here that there's some muscle memory to it in that let's say a whole company adopted this for all their projects. That the ability to jump around from project-to-project and maintain that muscle memory is strong. I'd say that's a bonus. And the idea that, like you said, you're not really writing any CSS, so you're relying on this toolchain to have all these classes available.

In development, you just go buck wild and use whatever you want and then have the build process step be like, oh, I see what they're using here. They're only using these, say, 78 classes. I'm going to produce a style sheet that only has those 78 classes in it, which is probably a tiny fraction of the whole library. There is this, like, performance benefit to it in that you're shipping style sheets that are honestly probably a lot smaller than the stylesheets I ship.

Dave: Mm-hmm. Yeah.

Chris: I don't have a huge problem with the performance of style sheets, but it is significant. The size of a style sheet -- often CSS is linked up in the head. It's a blocking resource like the HTML parser gets to that link tag. It finds that style sheet. It starts downloading that style sheet and it's also saying, do not render anything until I have the style sheet ready to rock for you.

Dave: Mm-hmm.

Chris: That's a significant type of resource. We're not really lazy loading or that kind of thing for style sheets. They're kind of too important for that. That's a big deal. The smaller your style sheet in the head, that's a performance boost.

Dave: Well, if you can even take that a step further and you figure out your critical CSS, you can inline stuff in the head, you know.

Chris: Right. Right.

Dave: That's kind of cool, too. That's just maybe an argument for more vanilla CSS. I'm sure somebody has written Tailwind critical CSS at or whatever, but I think what you're saying, too, is like, when you buy Tailwind. You don't buy it. I guess you buy Tailwind UI. But when you buy Tailwind, you're also buying this purge CSS flow or hopefully you should be.

Chris: Right.

Dave: But even the Tailwind, you have to use a post CSS plugin, I think, or Tailwind kind of has a post CSS plugin. It comes with a toolchain is all I'm saying. Sass is also a toolchain.

Chris: It does and it's a toolchain that you have to be hyperaware of what it's doing and how it's doing it. For example, on CSS-Tricks right now, one of the things that happens is that I write my own little Ajax request to my own server that says, get these ads. It actually runs three different Ajax requests when the page loads. It hits my own server and says, get the ads that I've hand-coded into this file. Then hit the ad server and get how many ads they have and combine them. Then if there are too few, hit this other ad server and fill up the spots with what you get from that. It's like my own sold ads and a network sold ads plus a backfill if there are too few. Right?

Dave: Mm-hmm.

Chris: It gets these and it templates them using, you know, just a backtick tag, you know, template literals.

Dave: Mm-hmm.

Chris: Then plots them onto the page. It all happens pretty fast and whatever. It's an ad network approved way of doing this.

Where does purge CSS look to find those class names? Do I say, "Look at all my PHP files and get the class names that you find out of it," or "Look at my JavaScript template and find it all"? Is it going to know to look in the right places to find the class names within this random template literal on some random.js file? Is it finding those too? Maybe it is and maybe it isn't, but I think I've read that you kind of need to train it to where to look and stuff.

Dave: Mm-hmm.

Chris: If I just start using new Tailwind classes then in that template literal, maybe purged CSS doesn't know they exist. Maybe it's going to make a style sheet. Then it's missing some classes that I need for those. That just buys you a little technical debt, a little, like, ooh, no, I've got to manually teach this thing about where to look or manually teach it to automatically include these class names because I know that I'm going to need them.

Dave: That might be a problem you don't discover until the production bundle gets generated, too, so there may be a gotcha there.

Chris: Right, because on dev it doesn't do that. Yeah.

Dave: But again, I'm Dave Rupert 2020, trying to be open-minded.

Chris: [Laughter]

Dave: I think I realize it's not my favorite thing but I definitely see the advantages. Like you said, if somebody is -- they have four or five apps all using this, they're leveraging a communal knowledge, you know. Tailwind provides that communal or the framework. It provides the established pattern and that's probably very valuable to your company. That's the situation one of my clients is in. Their app is written using Tailwind, so we should make the marketing site written in Tailwind. That's an easy, easy call.

Chris: That's interesting. Yeah.

Dave: We'll just use it.


Chris: I like to be dragged into things too. Don't you? I'm on a project. I don't get to make the technical choices, so I'm being forced -- force exposed to some things. Whether I like it or not, I'm going to do it. Sometimes, I end up resenting it and sometimes I like it because I'm like, well, I never would have had that experience if I wasn't because I'm not the leader of this project. I'm just on it.

Dave: Yeah. Yeah, I mean that would be -- it's kind of nice to just--whatever--get an experience. You're just like, okay, well.

Chris: What about being told? I think we have lots of evidence. We've probably mentioned this many times in the history of the show that there are developers, including us in this, that like to just be told what to do. You know? The classic is rails. There's a Rails way to do things. You just do it that way.

Dave: Mm-hmm.

Chris: That can be awfully nice because you buy in a lot of benefit from that. You can hop around projects. Do you think there's an element of that here too? With just raw CSS, it's just an open hippy fest. Do whatever you want in this file. But with Tailwind, you have to do things a certain way or it doesn't work.

Dave: It is. It's a blank canvas. The empty CSS file is a blank canvas almost quite literally. You apply every style that goes on the canvas whereas a Tailwind or something, that's--I don't even know--like a spirograph or stencils or something. It's a pre-designed way of doing something. It's an instruction. It's IKEA or something.

Chris: Mm-hmm.

Dave: You're able to, like, okay, I just need to do this and this and this to get the job done. That's great. That makes my life easier. I can respect that.

Chris: Mm-hmm.

Dave: Go do that. I think any of these -- I think that's what frameworks offer. Rails was like, hey, every time everyone makes an app, they do these ten things. We're just going to solve these ten things, like how to fetch data, how to render data, how to do that in a sane way. How to--whatever--connect to your database, do the routing, you know, the server routing. You'll never have to touch an Apache config again. Rails kind of did that and that was great.

I think there's establishing conventions of ways to do things. That's pretty awesome. I'm a big fan of conventions and stuff like that. I think, too, there's maybe this idea like some people just want to shortcut. Again, I'm kind of like, there are no shortcuts. Your complexity is going to live somewhere.

But some people just want a shortcut and it might feel like a shortcut for a while. It's like, you know, I just install this and, like, I can just write. I don't even have to worry about CSS and that removes one trouble from my life. You know what? That's great. The HTML gets a little muddy but whatever. [Laughter] I'm going to be here for six months or something.

There's a lot of HTML now, but you know what? It's better than dealing with a lot of CSS. You know? For some people, that's probably a good tradeoff.

Chris: Yeah. It probably feels great.


[Banjo music starts]

Chris: This episode of ShopTalk Show is brought to you in part by Wireframe. Wireframe is another podcast that you're sure to like. Whether you're into UX, UI, technology, just curious about the way that design impacts our everyday lives, you should check out Wireframe.

The host is great. It's Khoi Vinh. You know Khoi? A blogger that I totally look up to, an amazing designer, you know, is kind of behind a lot grids on the Web. Has a book about that. Has this whole history at the New York Times. Now he's the senior director of design at Adobe and this podcast is brought to you by Adobe. They're really putting everything into it. It's super well done.

I hope you like this show. But, largely, it's Dave and I. We hit record, hit stop, make sure it's polished up, and put it out there. It's just this conversation between Dave and I and an occasional guest, but we don't spend weeks planning a show, storyboarding it, getting the perspective of ten people, putting it together with amazing sound design, and all this stuff. You know those kind of podcasts are on another level. This is one of those podcasts that is on another level.

As much as I want you to listen to this show, I'm sure you already listen to some shows that are in that category of super good. This is in that category of super good. I just listened to one that was so great in Season 3 called "Why Can't Dad Unmute Himself on Zoom?" It talks about the fact that he can't, the fact that you have to help do that is a design problem. It's just a very interesting one, so if I recommend any episode, check that out. Just search for Wireframe in your favorite podcast app and there'll be a link, of course, in the show notes to it. Thanks so much to Wireframe for the sponsorship.

[Banjo music stops]


Chris: Andrew Sipe, he says, "When I attempt to build a site from scratch, I get overwhelmed. Are there resources that have all the components, layouts, you know, et cetera, but allow me to put the parts together myself like a box of Legos? You can follow the instructions and build what's on the cover or you can deviate and build a few smaller sites or go to a completely different site? When I start with a blank slate, I find myself going down a wormhole of websites looking for resources, components, inspiration, reading about all the different ways you can build a site and then I never actually build anything."

That blank canvas thing is a little rough for Andrew. I would mention -- why don't you go first?

Dave: What do you do for inspiration when you've got a blank canvas?

Chris: Yeah, and what are the things that are like Lego blocks if you're absolutely screwed by that? Is there--I don't know--Lego blocks of Web development?

Dave: I mean the place where I start always, I mean, if you're stuck or have no ideas, if you just pull out paper, graph paper, and just sketch an idea, the distance from sketch to CSS Grid is so low. You could take a sketch. If you did it on graph paper, it's almost quite literally just count the number of squares you drew and render out the graph.

I don't know. Maybe I'm not saying it, doing it very well, but I don't know. I'm not doing this question justice. I don't know.

Chris: I can tell you about my experience when I was a super beginner is that I started with WordPress and I installed the thing and I had a WordPress theme and now I have a site. It's doing all the stuff I want it to do. Now all that's on me is getting content in there, deciding if that design works for me or how I can change that design. I was really into the design stuff, you know.

Dave: Mm-hmm.

Chris: Write a blog post, sure, but I thought it would be fun to make the site look how I wanted it to look. There's no blank canvas there. Day one, you've got a fully rocking site.

Dave: Yeah.

Chris: That's largely because it's a framework and it has themes too. Anything that has a theme to it, you'd have that same experience for. Install Gatsby. Gatsby has got a bunch of themes. 11ty has some nice starter themes. What's Andy's?

Dave: The Hylia.

Chris: Hylia. Sure. That's a wonderful starting place for an 11ty theme. It has some incredible performance right out of the thing. Now, you're not starting from scratch. You're starting from that.

Now, I don't know if those are all necessarily Lego blocky. If you're looking for Lego blocks, maybe a design system thing might work for you. Maybe it's literally Bootstrap. Maybe those are the components or maybe it's Ionic or something that are actual components.

Dave: Mm-hmm.

Chris: If you like thinking in the components type of thing, look at some of these open-source design frameworks.

Dave: Yeah. I think, too, design is practice 90% of the time. You have to make a hundred things to start understanding what good design is.

Chris: Mm-hmm.


Dave: Maybe you already have a good sense of design. Copying is always one tried and true way.

Chris: Oh, hell yeah. Like just with a heart full of envy, too.

Dave: Yeah.

Chris: I love this and I'm just going to copy it. [Laughter]

Dave: Yeah. There's one site -- there's some site recently and they did that that's fixed on the bottom and it just reveals or whatever. What is that trick?

Chris: Yeah, it was like a -- okay.

Dave: It was basically like the footer; the curtain goes up and shows the footer at the end of the page or whatever. The page acts like a curtain. It was awesome. Immediately, I'm like, I'm doing that.

Chris: I called it the slide-out footer and the site was called The Markup, which is

Dave: Yeah.

Chris: It's still a beautiful site.

Dave: So, I just saw that and I immediately was like, "This is on every page! I'm doing this!" But I didn't do it.

Chris: Yeah.

Dave: Yet. I'm gonna.

Chris: [Laughter]

Dave: I didn't do it yet, but you know. I think that's always a good -- but don't steal the design, you know. I think that's tough, too. You just steal a design?

Chris: I ended up not feeling bad about it, usually, when I do it because, while you're doing it, you end up making different choices anyway.

Dave: Right. Right.

Chris: You're like -- you know.

Dave: I just mean like copy and paste from the CSS file.

Chris: Oh, right.

Dave: Or copy the HTML and junk it into your site. I mean I just -- you can -- there's still plagiarism is still a thing, you know, and I think you can kind of discredit yourself. That's kind of maybe a weak, like, academic notion or something. But it's not yours. Make something that's yours, especially if it's your website.

If it's a client's website, man, I can't tell you how many times I've been in the client website and they're like, "Just copy Apple," or whatever. It's like, "Well, first of all, we're not just going to copy Apple, but what is it about Apple that you like and what can we do to make that?" Everyone wants that. Everyone wants something they saw, and so maybe it's like mood boarding. You piece together things you like and kind of come up with something.

Also, figuring out your content, like making post-it notes and writing the blocks on post-it notes and arranging them in a column of hierarchy and importance, that's huge.

What's the most important thing? What has to go on the home page? Oh, a picture of this illustration I made my friend Kyle make me. Cool. That's number one.

Number two, I probably need to introduce myself because no one knows who I am. That's number two.

Number three, my articles. I spend a lot of time doing articles, so I should put articles there.

Number four, you know, I'll talk about my side projects. There you go.

Number five is a footer. Dingo-bingo-bango, I'm done. That's it.

Now I have the hierarchy established, right? That's a big word but what's most important is established via the mobile column. When I go to my desktop view, the hierarchy should stay the same. Usually, hierarchy is bigger, is more important. Think about that. If this is truly more important, you make it bigger. Ta-da!

Chris: Yeah, I love that. I love that. That's so good.

You have to think about that sort of stuff when you -- that's just basic--whatever--design but if it's important, make it bigger. If it's not important, make it smaller. Not too small that it's inaccessible but use size. Size is your friend and that's where I go back to drawing boxes on graph paper. You can erase pencil marks. Did you know that, Chris? You can just erase them and redo them. It's changed and you didn't write any code.

Chris: Doesn't it sound so simple? It's funny, right? Just arrange it. Just make the important things bigger. It's like when you talk about it, it seems like a kindergarten project only it's not. It's a life pursuit of getting it right. It's so crazy.

Dave: Yeah. Yeah, it's that, like, whatever.

Chris: It took me 20 years to draw this in 5 minutes, or whatever.

Dave: Yeah, it took me 20 years to know how to draw that line, or whatever.


Chris: Which is just beautiful. It's a little pretentious, but it's also perfect. You know I was looking at this slide out footer. I remember I was going to, like, oh, let me do a little article about that. That's CSS-Trickery and isn't that like my literal job?

Dave: Hmm.


Chris: I kind of did it, you know, and looked at how they did it. They use what are called magic numbers.

Dave: Magic numbers.

Chris: In their case, they're not so magic because they must measure it with JavaScript because I see there's an inline style. Imagine how you might do a footer like this is that you'd add margin to the bottom of all the main content on the site such that it makes a big gap below it. You know?

Dave: Mm-hmm. Mm-hmm.

Chris: Then the footer then can go in that gap. But you don't want to use too many magic numbers, so maybe you just let the footer just be as big as it wants to be. Then in their case, they measure the height of that footer that's just whatever it is because it might change with different fonts loading and different user styles or whatever. They measure that and then apply that measured height to the margin-bottom of the main content. It's kind of a magic number.

I'm looking at their site right now and that margin-bottom is 313 pixels applied to an inline attribute on that main content. It's kind of starting to replicate that, like, here's how you do it with magic numbers. Here's how you measure it. Then I was talking with Shaw about it on Team CodePen and he tried a different technique where, instead of position fixed on that footer, he used position sticky.

Dave: Mm-hmm. Mm-hmm.

Chris: It just works.

Dave: No magic numbers.

Chris: It's just like -- yeah, it's a slide-out footer technique with zero magic numbers. It's like you always think of position sticky as top some number. You know? like top zero probably.

Dave: Mm-hmm. Mm-hmm.

Chris: But it could be like top 20 pixels to push it down a little bit.

Dave: Yeah, you think it's sticking to the top, right?

Chris: Yeah, but in this case, he's using a bottom zero position sticky, which is really mind twisty to me how that works.

Dave: [Laughter] Those browser people. They thought of everything.

Chris: Yeah.

Dave: Well, yeah.

Chris: Pretty fun. That was a nice -- that was a nice Dave tirade. I really enjoyed that.


[Banjo music starts]

Chris: This episode of ShopTalk Show is brought to you in part by Framer. Literally, Go there to sign up for free or to get 20% off if you go for any of their paid plans, which is super cool. Thanks, Framer.

Good design work, it should clearly communicate a message. The same is true for you, a designer. You should be clearly communicating a message. To who? To the people you need to sign off on your design: your manager, your client, your CEO. Why are you still presenting flat, lifeless product ideas? Put an interact prototype into the hands of those people and watch their eyes light up and they'll buy into your vision. It's much more convincing to present an interactive prototype. Framer is your secret weapon.

Start from scratch or import work from another design tool. Drag and drop. Build these powerful, interactive components. Set up transitions, animations, you know, which is like almost expected these days that your app has when it's moving from one page to the next or one state to another state that it has transitions to get you there. Create your own stunning animations, all visually. It's a Web app. Beautiful for it.

Rich, realistic prototyping just became intuitive in Framer. Just take it from Bruno, a product designer at Shutterstock. "Framer is an extraordinary resource for rapid prototyping. It has improved our team collaboration by providing an easy way to share the designs between engineers and project managers. Its built-in tools have been essential for quick prototyping and users testing."

Oh, how awesome is that? Again, that's where you can sign up for free to get 20% off any of their paid plans.

[Banjo music stops]


Dave: Uh, hey, so I was going to say I do -- I have ran my mouth a little too much. I have a correction. I'd like to issue a correction here. The first correction ever on the ShopTalk Show.


Dave: The other week, Scherp wrote in and asked about, like, SVGs that are way too big and I think using a PNG would be better. We were like, "Nah, just use the SVG." Literally, that day, I started watching one of those Web dev live videos that Google did the other month - in May, I think. There's a video called Image Compression Deep-Dive with Jake and Surma where they say, "Sometimes an SVG can be too big and perform worse than a raster image," so I'm going to eat my words here. But I think it has to be pretty big or pretty complex, so there you go. You can send too much math, but just careful there. Anyway, I want to say that.

Also, Web Component people, we mortally offended, and we'll figure that out as we go.

Chris: I know. I hate to get right into that right away, but one of the -- [laughter] There was some good points, a little bit, in that these frameworks that we talk about, the technological buy-in of using a component that's built in different technologies, there was a little bit of, like, "It doesn't matter. They are these little two kilobyte, three kilobyte, seven-kilobyte libraries. The eyeball of the Mona Lisa when you ship an image is bigger than that," kind of thing.

But it's like, meh, okay. Let's set that aside for a moment. The one I always focus on is that, like, I'm not talking about just using yours. I'm talking about building mine. If I build these -- if I use some particular library to start building mine, I'm still choosing a technology that has a build process that's somewhat at least unique to that framework. I'm buying into a toolchain when I do that. To say that Web Components are just tool agnostic, you know, do whatever you want with them, I think is a little disingenuous, but we can leave at that.

Dave: Yeah. Yeah, I mean, you know, I said, I guess, correction number two, the second correction ever on the ShopTalk Show, I said ING Lion, which is their Web Component system. I was like, oh, that comes with whole design system. That is not correct. They have an ING designer. There's a skin. This is the components and they do have some CSS, but you can override that CSS. The whole idea with ING Lion is you pull down the button and then you extend their button primitive. Okay? So, there's Web Components and then ING Lion sits on top of that and then you build your components on top of that with your styles or whatever.

Okay, but I think the thing I was confused about specifically was, like, when you open ING Lion button or whatever. It could be Carousel or whatever. There's an important statement at the top that you're pulling in a bunch of pieces from Lion Core. For me, that was sort of like, "Okay, what is Lion Core? I have no idea." I'm pulling stuff in, but that's probably some accessibility stuff. It's probably some just standard even handling kind of behaviors and stuff like that. But again, I have to learn a system, a separate system, it feels like, just to use a button.

Again, Lion is actually pretty good, the more I dug into it, but you kind of have to learn a separate system. Then somebody had linked me to an article. This is all helpful, but it was an article over on, I think.

Chris: Mm-hmm.

Dave: It was just comparing these kilobytes of each framework or each Web Component generator or interface. You know it is. It's two to three kilobytes and it's the cost of, like, 30 components on a page or something like that. It estimates that. But I was looking at that and there are 33 different Web Component generator libraries. I just was like, "Whoa! This is way more than I thought, but that's where it's starting to get confusing, too, like if you had to operate or PR something. That's a lot to me. I do wish there were kind of front-runners, but then I've heard the argument there should -- you don't want kingdoms. You don't want kings in Web Component land, you know, highlanders. You don't one to rule them all, which that makes sense too. I'm behind that. Just like browser diversity, you want Web Component diversity or something.

Chris: Yeah.

Dave: Framework diversity. For me, I think it's a marketing problem. The discovery of these is very hard. There are a lot of players right now. Then you go to the awesome list for Web Components, awesome Web Components, and there are a few dozen. There are dozen design systems that use Web Components. There are a dozen Web Component frameworks that just use Web Components. There are a dozen or two, three dozen generator things that generate Web Components. That's where I think the landscape is very messy right now and so I wish it made more sense.

I think we had discussed before, too, the styling. I think a better understanding of the landscape is the one thing I want and then a better understanding of the styling story, how to style effectively, that's important too.


Chris: Every single -- you know I updated an article this morning on styling Web Components because somebody had written in that said some of the demos didn't work and this reminds me of some classic jQuery stuff. I was using, in the components that I was demoing, the constructor of the Web Component to do a query selector inside the component to find some of the stuff and all that. It worked for me because I would run that JavaScript after the Web Component exists on the page but not everybody does that. Some people link up their JavaScript in the head and stuff. When you do that, that's okay with Web Components. You just can't do it in the constructor. Then you've got to do it in the connected callback if you're going to do any DOM querying and stuff because otherwise, you know, the DOM is not there yet. It doesn't know how to find it. It has to use that callback.

I updated all the demos to connected callback, but I was demoing all the different ways you could style and they just all sucked to me. [laughter]

Dave: [Laughter]

Chris: I was like, I don't like any of these ways to style Web Components, really. You know?

Dave: Yeah.

Chris: I know there's different stuff coming or whatever, and I admit to some extreme ignorance here because, again, I don't ship any products with Web Components. The biggest ignorant thing to me was, I didn't know that they were designed not to be used raw.

Dave: Mm-hmm.

Chris: They were designed for frameworks to be built on them. That's how you're "supposed to" use Web Components and I really did not realize that. I thought the point was to just use them and I didn't get it.

Dave: Yeah, well, why would you think that? Because everything else is designed just to be used. I don't know. That's my thing. It's maybe too low-level, but you know.


Chris: Here's another thing that's not used enough. Sam Rowe writes in, "Why isn't there a much bigger focus in the Web community on using Web Workers? They certainly have a lot less APIs available to them than the main thread and are a bit awkward to use but, given how much noise there has been in recent years about JavaScript and Web performance, in general, I would expect there to be far more tooling, libraries, blog posts, et cetera, to help people make good use of them. It seems crazy that people have been walking around with eight-core phones for years now but the Web still insists on trying to squeeze as much possible performance out of just one of them." Fair enough, Sam.

Dave: Okay. You're putting JavaScript on blast here.


Dave: I think you're right. A lot of JavaScript could be moved into a threaded system, but I think it's hard. I don't think people understand that. That gets into asynchronous code, which is kind of a problem. Promises. You know?

I actually wrote -- I tried to write a framework. It's a baby framework, but it's basically like all the work happens in the worker. Your view template, all the logic in your view template is basically just calling the worker and saying, "Go fetch data. Manipulate it and come back to me." It's called Worker Controller. Don't use it ever. I'm just playing around.

It's just this idea of, like, can you--? I just was curious how you -- I don't know -- how you make this happen.

Chris: Mm-hmm.

Dave: I liked it, though. It was very efficient. But how you get it all to play with, like, a router and stuff like that because what's weird is, like, you're not just -- you have to reference a specific file, and so you have to be like new-worker" or worker1js or whatever. That's hard. I wish you could almost write workers in line and then they get split out. Then wouldn't that be cool? I think Surma from Google has this thing called Comlink that kind of helps with this.

Chris: Yeah, that was like his life's mission for a while, right? Telling people exactly this. You've got to start using Web Workers, people. My gosh. They're amazing for performance.

Dave: Yeah. If you go to a -- what was their show? Supercharged? Was that Surma and Paul Lewis? They would do that, you know, try to make these things work.

Chris: I just don't. I get the concept. You can start up a new JavaScript thread and you can talk to it and you can make that Web Worker do jobs for you. If jobs are -- basically, if they're not UI related, if they don't need to be done as fast as absolutely possible because that's a performance thing, too, sometimes you want JavaScript doing things as fast as possible. I know Web Workers are fast but, by nature, they're async, right? You need to give it a job and then wait for it to finish the job and then give it back. I just don't -- I can't think of a million things where that's useful for, but that's just my own ignorance. I'm sure there's plenty of things. It's almost like I wish just like -- I don't know. I wish React would just do it if it new it could use it or something. I almost want my tools to just know when to use a worker and when not to and then do it for me because my brain is striking out on times to use it.

Dave: You know, so I've used them a few times in my life here on that little experiment. On the Paravel Inc. homepage, if you go to that, there's a big image. I made this thing called color cycling. It's like an old Atari. Not Atari -- maybe Atari, but neo geo, if you remember that, those old fighting games. They would kind of do this to their background images and they'd cycle colors. They were like, "Oh, change this blue. Make all the blues go from blue, white, green, blue, white, green," and it makes like water cascade and fall.

I'm doing that on my homepage on Paravel Inc. You know if I do that in the main thread, it does not like that, and so I'm using it for a fire effect. I'm manipulating pixels on this canvas, on this--

Chris: Oh, it's canvas.

Dave: On this JPEG.

Chris: Okay.

Dave: I'm using -- yeah, I had to render it all in canvas, and so I'm sending -- I'm making the worker do all the calculation and then it posts data back to the main thread and the main thread just paints the canvas. Does that make sense?

Chris: Yeah. Yeah, that's a great use case. That seems good.

Dave: And so, I got a lot of performance by moving it out to a worker. There's still work to do. It's all kind of eight-bit, but I was kind of actually trying to hit four frames per second because that's kind of more like eight-bit games would do. When you're doing intense calculations, that's a great place but, really, any time you're using an async function, you could actually be spinning that out to a worker.

Chris: Oh, see! There you go. That's a good way to think about it. If you're using async, it could be a worker.

Dave: You know you think of your standard file, JavaScript file where you wrote an async function. It's usually one out of ten functions that you're like, "Oh, I should make this one async," you know, or something like that … my experience.


Chris: Yeah. I'm still not even at that moment, but I had it the other day because I was on this little open-source project and I submitted a PR for it. The idea was that, like, in this game, messages from the network come across the wire. There's like a chatroom, right?

Dave: Mm-hmm.

Chris: A new chat message arrives. Cool. That's fine. It was working fine. It's a perfectly working feature in this product. But, you know, sometimes when I'm developing in a product, I'll just hit command R and refresh the page, you know. When I did that, then all the chat history was gone because it didn't save.

I was like, let's save them. Let's persist those chat messages into some kind of store. There are a million options for that, but it happened to be an Electron app and Electron has this project called Electron store that looks pretty good for it. We were already using it for some other stuff, so I just chucked this stuff in an Electron store. Then when you load the page for the first time, yank them back out and try to do it performantly. Don't store ten million messages in there. Have a cap to how many that you're willing to render on the page and store and all that stuff.

Then I submitted the PR and the leader of the project was kind of like, this is pretty good proof of concept but let's not keep them in the store. Let's keep them in a flat-file - for some reason, I don't even know why. But also, the most important thing is make sure that all of the writing to it, pulling from it, rendering it to the page, they're all async functions because they're not critical to the game. It doesn't matter if it takes a second for a chat message to arrive. Who cares?

Dave: Yeah, so if you click a button, the settings button, you want the modal to fly up or whatever. That's critical to the UI.

Chris: Yep.

Dave: But clicking the chat button, you want to see the chat. That's critical but when the messages show up, that's not critical, right?

Chris: Right. Right. Right. It might be the first async function I wrote in my life, but it was on a class, so I just put async in front of the function name. [Laughter] That was my solution so far. Is that good enough?

Dave: That's my thing, yeah, is like, I'm just going to type async here - question mark.


Dave: That does it?

Chris: There should be async question mark.

Dave: Yeah.

Chris: That should be a native JavaScript thing it's like, eh, make it async if you can - if you can.

Dave: Yeah, if it doesn't do anything, that's fine. I'm cool. Don't worry about me.

Chris: Yeah.

Dave: I just wanted to use await here. I didn't want to write a promise. Yeah, that's like my -- I was hoping Raymond Camden -- he's a very talented guy who does a lot of Vue stuff, but he was migrating an old project and he was like, "I'm having a problem. I push it to 11ty to Netlify and it's bombing out." I was like, 11ty and Netlify? I know those things. [Laughter] I'll help. I know. I'll help.

It just was never -- 11ty was never exiting. It turned out he was fetching data, like getting data from a data source using Mongo, and he had some async functions. I just was like, "Ooh, this maybe is the one place it could be going bad." I commented out the file. Ran it. It worked. And so, I was like, "Okay. Okay. Let me go in here and see what's going on."

It was like he opened a connection to the Mongo but it never got closed, which is an honest mistake. If you're running a node app, you never close the connection to the database. But when you're running a serverless app or a static app, you can't just keep the connection open. Right?

I found the bug, I guess, but it was very interesting because it was just this idea, like, okay, I can type client.close to close the Mongo client, but I bet I actually have to type awaitclient.close because I bet it's some kind of promise that has to resolve and then it comes back. It was a few tricks there, man. Async is tricky, I guess is what I want to say. I don't know how we got onto this question. I forget.

Chris: I actually don't know.

Dave: I'm still not seeing questions in the thing, so.

Chris: It was Web Workers, you know.

Dave: Okay. Yeah. Yeah, I think any time you're using a Web Worker or async, you could try a worker but that's muscle memory and I don't do async every single day of my life. I do a lot more boring. I'm way more on the UI side of things, and that's typically where you want main thread, you know.


Chris: Is this server? I guess a Web Worker -- let's say you had a big, a one megabyte JavaScript file or something that took requests and processed them and returned them. That's a big -- you'd probably not load that in any kind of critical path, but let's say you detect the network as fast or the user is idle or something. You grab that one megabyte JavaScript file off the server and you chuck it in a service worker instead or something because then you're like, "Oh, that'd be cool," because then -- or as a Web Worker, I guess. But a service worker seems better because it will hang out then. It'll stay.

Can a Web Worker then hit a service worker? I guess why not. Of course, it could, right?

Dave: Yeah, I think so. You could preload all those too. What's interesting, too, is serverless functions. Those are basically workers too, you know. You're saying, "I'm going to do all this work but I'm going to not do it in a thread, on the main thread or on a separate thread. I'm going to do it on the server and it's going to come back to me with the answer." You could. That's -- I don't know. As good as workers are, serverless could also be good because that's just a function that runs.

Chris: Oh, yeah.

Dave: If that helps you think about it, too, serverless and Web Workers and async functions are all kind of the same technology. It's stuff that happens later. But is it on your computer? Is it on the main thread?

Chris: Is it at the edge? You never know.

Dave: At the edge.

Chris: Yeah.

Dave: So--

Chris: Yeah, we had -- I think, on CodePen, as I speak right now, we have one preprocessor that runs locally if it can. We try to do that technique. It's Babble. We run a local copy on your machine of Babble without you even knowing it.

Dave: Okay.

Chris: If it's not ready, that's okay. It'll just go up to the serverless function to do it. But if it is ready, you'll use it. I think we're going to tear it down, not because it's not a good idea but because it's a one-off in the app. It adds some complexity to the rendering pipeline that it's like, "Oh, if just wasn't for this one, everything would just be consistent. Everything would be treated the same way." I think that's cool. At least we proved it out. I'd rather do all of them that way or none of them that way, rather than one.

Dave: Yeah. It should be -- whatever. You don't one-offs.

Chris: Yeah.

Dave: Ideally.

Chris: Well, that was fun. I guess we'll leave it at that, huh?

Dave: Yeah, we can wrap it up. I think if we start another question, we'll be ten miles down the road. [Laughter] We should stop it here.

Thanks, everybody, for listening. Thanks for giving us feedback, too. Really, I'm sure we -- we usually get everything right, so--

Chris: [Laughter]

Dave: If you ever hear us say one tiny thing wrong, please let us know. We appreciate that.

Follow us on Twitter, @ShopTalkShow. That's the best place to reach us or correct us.

If you hate your job, head over to and get a brand new one because people want to hire people like you.

Chris, do you have anything else you'd like to say?