574: Estelle & Eric on CSS The Definitive Guide, 5th Edition

Download MP3

Estelle Weyl and Eric Meyer join us to talk about the 5th edition of their book, CSS: The Definitive Guide. We talk about some of CSS' biggest blunders, custom scroll bars, single line comments, shorthand in CSS, useless CSS trivia, and how to get started learning CSS in 2023.



Eric Meyer

Web · Social
estelle weyl

Estelle Weyl

Web · Social

Time Jump Links

  • 00:13 Welcome
  • 01:08 5th edition of CSS The Definitive Guide
  • 04:29 CSS biggest blunders
  • 10:58 Should the browser be where we set dark and light mode?
  • 16:32 Custom scroll bars
  • 18:44 Single line comments
  • 25:20 Sponsor: Notion
  • 27:05 Why is display list-item a thing?
  • 36:25 What order do you use to revert?
  • 39:26 Should shorthand exist in CSS?
  • 41:57 Using outline instead of border
  • 42:59 Useless CSS trivia
  • 45:32 Case sensitivity
  • 50:46 Name spacing rabbit holes

Episode Sponsors 🧡


[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—covered in a thin layer of sunscreen—Rupert, and with me is Chris—fresh from picking his banjo--Coyier. Hey, Chris. How are you doing today?

Chris Coyier: Darn right, man. I'm doing super good. We haven't had guests in a while just because of scheduling crap on our part. But now we have some guests today.

Dave: Now we do.

Chris: And we might for the next couple of weeks if we do a good job. Two of my favorite people, absolute CSS experts, and that's what we're going to fill this hour-long episode with, if we possibly can. Although, Estelle... Hi, Estelle Weyl.

Estelle Weyl: Hello.

Chris: Has warned me that this might go over time. Turns out there's a little bit to talk about with CSS. And we have Eric Meyer here, too. Hey, Eric.

Eric Meyer: Hey. How's it going?

Chris: Awesomely! Congratulations, you two, on the release of a slim little book called CSS: The Definitive Guide 5th edition. Not a lot of books make it to their 5th edition, but yours has.

Anyway, it's an O'Reilly book that has now moved into their cool, new white cover format. You've got three fish, it looks like.

Eric: Yeah.

Chris: It's a good looking cover, I think.

Eric: Yeah.

Dave: Oh, yeah. For the listeners, they're holding up copies of the book. It is immense. It is a big, beautiful book. It is amazing.

Chris: Highly appeals to me, as somebody that wants to know everything there is to know about CSS, which despite attempting to make a career out of it, [laughter] I'm regularly humbled by little things. I'm like, "What?!" You know?

I learned that there's an e-pub vendor prefix recently thanks to this book. I'm like, "Where the hell did that come from?" [Laughter]

Anyway, yeah. It's, like I said, a nimble 1,000... What did you say? 1,126 pages butting up against the 1,200-page absolute limit of paper book technology.

Estelle: Printable books, yeah.

Chris: [Laughter] That's absolutely incredible.

Dave: That's very interesting, your limitation for the book was the number of pages that can physically fit into a paperback.


Eric: Yeah because obviously a lot of people read electronically now. But if you're going to take it to print then, yeah, you have to worry about those limitations. You have to worry about the atoms and all that kind of stuff.

Chris: [Laughter]

Eric: It's atoms.

Chris: Can we talk atoms? Yeah.

Eric: Yeah.

Chris: That's a phone to get from an editor. Yeah?

Eric: Indeed.

Estelle: Apparently, you also have to worry about page length for the e-version, too, because it's a huge download.


Chris: Huge download, yes, I noted from the Amazon website. It says, "Due to its large file size, this book may take longer to download." No joke, though. It is a lot of pages.

We've dwelled on this for a minute, but there's a comparable... There's almost like a cliché JavaScript joke. Somebody took a photo one time of JavaScript: The Definitive Guide, also a beefy tome of similar thickness. Somebody took a picture of it right next to Douglas Crawford's JavaScript: The Good Parts.

Is there a similar joke to be made? What is CSS: The Good Parts? Does that book need to be written?

Eric: No. Here it is.

Estelle: It just was.

Chris: [Laughter]

Eric: Yeah.

Estelle: And it looks....

Eric: ...writing.

Dave: The same book. Okay.

Eric: The same book.

Dave: Okay. Same book.

Eric: Yeah. It's all good stuff. The good part. All of CSS is good parts. Well, okay. there are a couple of parts that are not so good, but we talk about why they're not so good (in the book). There you go.

Chris: But very few, right? Isn't it still true? I think I was talking with... I can't remember who I was talking about it with, but this year we got... We'll get into all this stuff, but there are view transitions and all this new color stuff and the :has() selector. Every time something new in CSS comes out, this is what happens.


Chris: Everybody is like, "Aw... It's amazing!" Whereas JavaScript, they're like, "We're going to have classes," and people are like, "The hell you are."

There's just a lot of fighting, I feel like. I don't know if it's just the spirit of that community or whatever, but I don't know. CSS is just like, "Yeah! That sounds great! Let's do that!" [Laughter] And they're kind of right, usually.


Eric: Yeah. I know it seems that way. It's really not.

Estelle: What's the app cache of CSS?

Chris: [Laughter]

Dave: Ooh, yeah! What's CSS's biggest blunders? This is a good TikTok.

Eric: Um... Probably aural CSS, A-U-R-A-L.

Chris: Oh...

Eric: Because not in the sense that anybody hated it but in the sense that it was underspecified, never implemented, and if you talk to accessibility experts these days who know anything about aural CSS, they'll say, "Yeah, that was not a good idea." There's a reason nobody ever implemented it.

Speech, CSS for speech is now back in the conversation, but as a "let's do it right this time," not "let's try to resurrect."

Estelle: Maybe media screen TV.

Chris: Yeah.

Dave: Ooh...

Eric: Yeah. Yeah, maybe.

Estelle: @media TV.

Chris: Was TV a keyword that just meant something?

Estelle: ...television.

Estelle: It was basically like they assumed that when you did, like if you did screen, it would be a different thing for projector and a different thing for TV. Not that everything was actually just a screen.

Eric: Right. Although, I did use the projector media type for many years. That's part of the basis for the browser-based slide show system I made, S5.

Chris: Oh, wow.

Eric: If you had media=projection, which Opera also did this. That's where I got the idea. If you had media=projection styles, they would be used--

Chris: In full screen mode?

Eric: --if a browser went into full screen mode--

Chris: Yeah.

Eric: --because the presumption was that you were projecting it. You were giving a talk or whatever.

Dave: Hmm...

Estelle: Oh, so full screen was--

Eric: I mean kind of. I don't want to say it was absolutely one-to-one full projection equals for screen. But it was, effectively.

Chris: Does it still work?

Estelle: I think that is the app cache equivalent.

Eric: S5 does still work. I don't think anyone is supporting media projection anymore. Opera might be, but because they switched over their engine completely to Chromium, probably not.

Chris: Yeah.

Dave: This is why browser diversity matters. It's for that one feature. [Laughter]

Eric: 100%. It's just that.


Estelle: The other really weird feature is the style sheet themes. I forget. If you give the title attribute to rel style sheet, you actually can theme. That I think is only supported in Firefox, so that might be another app cache in CSS.

Chris: The title attribute on the link element?

Estelle: Yep. When the rel style sheet.

Chris: So, link rel style sheet, which we've all written a million times because you have to do that for CSS to apply. Then an href.

Estelle: If you actually... If you put the title attribute on that element, it has a different meaning.

Eric: It's not the title. It's the rel. There's rel equals style sheet and then rel equals alternate style sheet.

Estelle: Okay.

Dave: Oh...

Estelle: If it's rel--

Eric: That's on pages 14 and 15, by the way, of the book.

Chris: [Laughter]

Dave: If we had read it, of course. Right? We would have known this. Right? Yeah.

Estelle: It is the title attribute that makes it--

Eric: In the UI, it'll show you.

Chris: It populates the menu? Yeah.

Eric: Right. It'll give you a little dropdown menu. Yeah, the screenshot that we actually have for figure 1-7 to illustrate this is from Internet Explorer 5 for Macintosh. It was taken for the first edition.

Chris: Hmm...

Eric: And I've kept it, mostly. I actually had to fight a little bit this year with the editors.

Chris: To keep it?

Eric: Yeah. They were like, "This is really out of date. Could you please update it?" And I said, "No, I could please not." And they let me get away with it. We'll see if that continues.

But yeah, the title attribute was where you would name the style sheet, so you could have default and then title equals crazy colors - or whatever.

Chris: Right.

Eric: Then that would be your alternate style sheet. So, if you remember the style switchers of the early 2000s, which a lot of listeners probably don't because you were in grade school but whatever, websites would have... You could pick from a number of style sheets.

Actually, Jeremy Keith's site,, still does that.

Chris: It still does that, yeah.

Eric: Which I really love.

Chris: I'm sure it's not implemented that way, though, right? Is it?

Eric: No. It's implemented a different way. But that was a thing that was built into browsers. Yeah, Firefox still supports it, and I think that's it.

Estelle: I think that's it, yeah.

Eric: Safari did, but I think they removed it many years ago.


Chris: Okay. Okay. I'm interested in why you would fight for it in that way, though. You're a smart guy, Eric. You know that you can't even run IE5 for Macintosh if you wanted to. It would be a challenge to get there. But you wanted it in the book. Is it because it's the definitive guide or for historical reference?

Eric: For me, it's a little bit historical, and it's a little bit to show that, hey, this was supported 20 years ago. Those of you who were in grade school at the time might not know this, but this was a feature of the Web and we've actually lost it some.

Chris: Right.

Eric: It's a way without writing out and chewing up paragraphs on, you know, it was supported in this browser from this year to this year, and then they dropped it, and then in this other browser until this year when they dropped it, and it's still in Firefox. Right? You just sort of imply, "Hey, this actually has been around for a long time."

I do... I miss it a little bit. I miss that you could do that on multiple browsers because it was useful at the time.

As an example, we didn't have a prefers, like @media prefers reduced motion or prefers high contrast or whatever. I'd forgotten already because I can't remember everything in the 1,100 pages.

Dave: It's on page 889, I think it was. Yeah.

Eric: There you go. Yeah, exactly.


Dave: Yeah.

Eric: Probably more like 890, but regardless, there wasn't a way for style sheet authors to pick up from users, "Hey, I would really like to not have any animations," or "I would really like to have high contrast." Right?

You could write a high-contrast style sheet and then users could pick it in the browser interface. We do have more automated ways to do that now, which is nice.

Dave: This feels relevant with light mode, dark mode. I've even see people do sepia. I guess this is maybe a bigger discussion. Should the browser be where we set that, not in somebody's footer or something like that or the little moon toggle? Should the browser be helping us? I know, Eric, you kind of tangentially work on a browser, but is that something browsers should do?

Eric: I actually think this is a question for Estelle because Estelle works a lot more with accessibility, which is really what we're talking about.


Estelle: The browser, the user preferences, a user can set that they prefer reduced motion and a user can set that they prefer high contrast in their settings, the browser settings or the operating system settings. The browser actually knows what those settings are, so there's now media queries of prefers reduced motion and prefers high contrast. Users can select that without actually having to click on a link at all within the browser.

Chris: Right.

Eric: Yeah.

Estelle: There are debates between people as to whether it should be in the browser as an option or not.

Chris: It's almost like two different things, right?

Estelle: Yeah.

Chris: If you were really... If you were really, "We want this!" you could... A browser could implement it such that if it says background white, it's background black. If it's color white... You know it forces a dark mode on there. Whereas this is a little different. This is like if there's a dark mode available that's already been authored, make it available to pick from a UI, which is very different in the strength of what it's offering to users.

I don't know. I like it. I'd like to see alternate style sheet come back. It feels like there are these fancy browsers like Arc that I like to use that are like, "Yeah, we have Arc Boosts," and stuff. You're like, "Man, we had alternate style sheets back in the day."

Eric: Yeah.

Chris: But you read the specs, so we don't have to. Isn't it true that, for example, the input type equals date - or whatever - that the spec doesn't say, "It has to look like this"? And browsers are left on their own to implement it.

Estelle: Right.

Chris: Which mean that, on iOS, you get weird little dials. In Firefox, you get a little pop-down thing that lets you pick dates. And they do that on purpose because they don't want to be involved with that. Wouldn't that be the same for an alternate style sheet? They wouldn't specify what a UI picker has to be like in a browser. They would intentionally not do that.


Estelle: They intentionally don't do it for the input types because everyone's operating system has a default look. If you're going to get a color picker that's done by a developer versus the operating system, the user now has to learn this new system whereas they're probably accustomed to their default color picker from their operating system.

Eric: Right.

Chris: Hmm... Which they wouldn't be for an alternate style sheet. Maybe there'd be a selector or something, but there's no Mac OS version of a style sheet picker.

Estelle: You wouldn't really style the form controls in your alternate style sheet anyhow.

Eric: Probably not.

Estelle: Yeah.

Eric: There's a whole lot of, let's call it, debate around things like form elements. Should authors be allowed to make input elements look substantially different than they're used to from their operating system?

I could make an argument, and I know people who will strongly make the argument that, no; no author, no style sheet author (or designer or whatever) should ever be allowed to change form elements from the operating system defaults.

Chris: I could see it, like a full-throated argument that says, "No. If nobody did it, the Web would be more accessible because forms look the same absolutely everywhere."

But then you're like, "I just want..." Are you saying I can't use my brand font? That seems so chill, bro! Let me use my font.

Estelle: The is accent color, and you can change the font. But if you do something like if the data list element is not fully accessible because you can't style the options, so if you zoom into a data list, like the list that pops up with all the options, it's the original font size that the computer has. When you zoom in, it doesn't increase. You can't change the color. If you're using a data list with an input type range, you get the little tick marks, but you can't change the color of the tick marks. So, if the color of your background is -- I think it's 999 -- then you can't even see the tick marks.

Chris: They're gone?

Estelle: You can't change those colors.

Chris: Wow!

Estelle: Yeah.

Eric: Right. Yeah, and that's... Right. There are all kinds of concerns.

Chris: Are those mistakes or are they just the way it is?

Eric: Eh...

Chris: Yeah. [Laughter]


Estelle: We used to be able to style the Shadow DOM. The browsers used to make... I'm making this up because I don't know what the actual pseudo-element is, but it was like -moz--thumb, or -moz-range-track.

Chris: Oh, right. These proprietary.

Estelle: Obviously, not range-track, but they were proprietary, and then you could style them. But I assume people would not style it for high contrast mode. But since the browsers don't change it for high contrast mode anyway, I don't think.

Chris: A footgun, as it were.

Eric: Yeah. It's the same argument about custom scrollbars, right? I can't remember who I saw recently. He basically wrote an article. It was like, "Custom scrollbars: Stop it!"

Dave: Eric Bailey, I believe.

Chris: Yeah, it was Eric Bailey.

Eric: Was it Eric? Okay.

Chris: Yeah, and he made a good point. It was just like form controls, too. It's like you think you know what you're doing and you don't. Here's me over here being like, "I'm just making it bigger, Eric. Relax, you know." He's like, "No! Don't do it!" You know?

Estelle: I don't think it actually made it into the book, but there is a specification which changes the width, which allows you to change the width and the color of your scrollbar.

Chris: Right. It's very toned down, right? Firefox supported that forever.

Estelle: It's just two properties.

Chris: Right. Even the width, it doesn't take a pixel value, right? It's large or small or thin or wide - or something.

Estelle: Yes.

Eric: Thin.

Chris: Yeah.

Eric: Thin, medium thick, or medium wide. Yeah, I can't remember now. But yes, exactly.

Chris: Right. It doesn't allow you to do 100 pixels and set a background gradient.

Estelle: It does change it a bit, but it still keeps it looking like... It allows you to change it so it matches your theme.

Chris: Where do you land on it, Estelle? Does that seem okay, a reined-in version of that? Or would you still be like, "Nah, don't touch it"?

Estelle: I think it's better to not touch it. And the reason I think it's better to not touch it is because people do stupid things. If people didn't do stupid things, then I would like, "Sure." But you can't. With great power comes great responsibility. And unfortunately--

Chris: At least the colors. To me, just coming at it, just thinking from a CodePen perspective, we have all these scrollable elements on one thing. There are these little editors, right? If you're in dark mode and you're saying, "Don't touch it," and you're in a browser that forces those scrollbars to look light, I just think, aesthetically, it just looks really bad. [Laughter]

But that's okay. At least the spec says if you want to make them dark, you can make them dark. To me, I'm like, "Well, if it's part of CSS, I'm going to do it, gosh darn it."

Okay. Sorry. I made this about me.



Chris: Let's pepper some more CSS stuff in here because I like that we're bouncing around. It's fun for me to talk about absolutely random CSS things.

There was a little back-and-forth bloggy stuff happening about... Well, there's always this question about Sass and its features in CSS and stuff. But here's a tiny, tiny little thing that Sass does gives you //, like in so many programming languages, including JavaScript. Single-line comments.

I'm so curious from somebody that's researched the heck out of CSS and knows perhaps about its syntax. Is there any hope? Would that be a crazy 2024 thing to get - or something? Browsers being like, "Guess what! Single line comments coming to CSS near you."

Estelle: We've always had single line comments.

Dave: Ooh...

Estelle: Kind of because you just put a typo in something and you end it with a semicolon and you've got a single-line comment.


Dave: If you just failed the CSS, it's a comment - technically.

Estelle: If you fail a CSS line, yeah.

Dave: Yeah.

Estelle: Because it just ignores. As long as it's not in the selector because selectors are non-forgiving. If you have a selector block and it doesn't understand one, it'll be like, "Yeah, no, this whole thing is shot."

Chris: [Laughter]

Dave: I could just do $comment: and write my comment.

Estelle: Or you could do an :is().

Dave: Yeah.

Estelle: Put your whole thing inside an :is() or a :where() because those are forgiving.

Chris: Oh, your comment? So, what you're saying is we just need to update our syntax highlighting themes.


Chris: That's all we need. It just needs to make that gray, and then we'll all be happy.

Estelle: Please don't do anything I just suggested.

Chris: Ah! I love that.

Eric: [Laughter]

Estelle: But I often will... Because one of the things I like to do is I like to make my style sheet visible and editable so that people can play with it. I put an X in front of any property that I want or an underscore in front of any property that I want them to remove the X or the underscore so they can see the effect of this thing toggled on and off.

Chris: Hmm...

Estelle: So, yeah, it's kind of like a comment. So, you can take that to the extreme and actually write a whole comment because you could do content: and then put in quotes this whole thing, but it's not ... before, so it doesn't really matter. Right?

Chris: Yeah. We already have single-line comments.

Estelle: We can totally single line comment. Just please don't do it because the person who comes afterwards is like, "What the heck does this mean?!"

Chris: Oh, just rife with disaster.

Estelle: Yes.

Chris: Especially the absolutely has to end with a semicolon problem. If you forget that, then you're screwing up the next line, too, then, right?

Estelle: Yeah. True.

Eric: Yeah.

Estelle: But your syntax highlighter will tell you that the next line is screwed too, so it's okay.


Eric: You could put in your own vendor prefix like -my-comment: and then a string semicolon done.

Estelle: That's a smarter way of doing it.

Chris: Yeah. I like it.

Estelle: You should not be asking us ways.

Eric: Oh, we have so many--

Estelle: We can come up with ... ways.


Chris: It's not bad.

Eric: Yeah. There are so many ways to just mess up future CSS and future....

Estelle: Yeah. I mean I think that everyone should just put universal selector transition delay one second.

Chris: Oh, delay?

Estelle: Yeah.

Chris: Like an animation delay?

Estelle: Like just a transition. Yeah, put zero second space and then one second and it'll just delay all your transitions by one second. So, when you hover over, it takes a second.

Chris: Oh...

Estelle: We come up with really bad ideas for April Fools.

Chris: You're blowing my mind here. Why would you do that? That's horrible. [Laughter]

Estelle: Eric has one for taking one hour to rotate a page.

Chris: [Laughter]

Estelle: You put it on a page. So, when no one notices it, but if they leave it in a browser window, like a tab that's open, and they come back to it--

Eric: Yep.

Estelle: --four hours later, it's tilted like 30 degrees. They're like, "What the heck happened?"

Chris: What did you do!

Eric: Yep.

Chris: I was on somebody's website the other day that I swear to God I couldn't get it back, but they had a one-pixel breakpoint upside down in their website.

Eric: Oh...

Chris: Then I kept--

Eric: What?

Chris: I kept resizing my browser's window to try to get it back and I couldn't find it. So, I can't prove that that's what it was. But in my mind I'm like, "That must have been what it was."

Eric: Chef's kiss.


Estelle: Oh, so the Washington Post had that. The Washington Post had media queries where if it was larger than 1,400 (or something like that) it was one size. And if it was smaller than 1,399.9, it was a different size.

I managed to keep getting my browser stuck right in between the two. So, when it did that, it would be like... Because they did mobile first so it would be like 360 pixels wide.

Chris: Hmm...

Estelle: So, it would go from 1,400 to 360 to 1,399 (or something like that).

Eric: [Laughter]

Estelle: And so it took me... I sent them some screen... some videos, but it took me a really long time to actually get a screenshot with the developer tools open because I had to figure out exactly which point--

Chris: Oh, you got it? It was a subpixel, too? Ugh.

Estelle: It was a subpixel, yeah.

Chris: Wasn't it a little bit like--? If you wrote two media queries that said, "I want under 1,400 pixels and over 1,400 pixels," that you could accidentally--? You accidentally... 1,400 pixels, neither one of them applied.

Eric: Right.

Chris: You're like, "Oh. Whoops!" [Laughter]

Eric: Yep.

Estelle: That's exactly what happened there. Yeah.

Eric: That's why one of the recent innovations in media queries has been having the little mathematical symbols.

Estelle: Greater than and equal.

Chris: The range syntax?

Eric: Right, range syntax so you can say width less than equal to 800 pixels. Then the next one is width greater than 800 pixels. Yeah, because--

Dave: To fix that problem?

Eric: Because exactly that thing you were just saying. It could happen to you where you would say max width 1,400 pixels and min width 1,400 pixels for the next breakpoint.

Chris: Yeah.

Eric: Weirdness could happen. Either they would both apply or, if you set it up a slightly different way, neither of them would apply at one precise pixel width.

Chris: Yeah. I've totally done it.

Eric: Yeah, exactly. With a range syntax, if you're careful, it's much easier to avoid those problems.

Chris: Yeah. It's way better. Good job, CSS.


Dave: I want to go back to this flipping the page around idea--


Dave: --because I feel like that could be a really important accessibility feature for people in Australia. You know?


Dave: When they want to read the site.

Chris: I know. Their toilets have media queries that make the water spin the other way. Why not websites?

Dave: Yeah. If we float the pages around for Australia, then they get a better reading experience.

Eric: Yeah.

Dave: No one is talking about this.

Eric: Yeah, yeah, yeah. I'm with you 100%.

Estelle: I think you could patent it.

Eric: By the way, sorry, I just want to say ranged media queries, pages 1,038 to--

Chris: Ranged...

Eric: 1,038 to 1040 in the book.

Dave: Whoa! That's almost to the end of the theoretical limit or the physical limit.



[Banjo music starts]

Chris: This episode of ShopTalk Show was brought to you by one of my favorite pieces of software and that's Notion. Today, I'm excited to share that they just launched Notion Projects, which includes new, powerful ways to manage projects and leverage their powerful, built-in AI features, too.

One of the ways that you can do project management with Notion is to make a database. If that sounds scary, it's not really. You can start as a spreadsheet. That's a helpful way to think about it where there are rows, and you control what the column types are. You can say, "What is the state of this particular task? Who is assigned to it? How long is it going to take?"

There's actually a new feature that's like, "Well, what GitHub pull request is associated with it?" If you're thinking of it like that, as this spreadsheet structure, you can view it like that and sort it like that and filter it and all these powerful possibilities. But you can also view it in different ways.

If you attach a date field to it, you can view the whole thing as a calendar, and that's kind of useful. We use it right on ShopTalk Show for looking at the calendar of dates when we're recording and publishing things and all that.

But a more common way that I use it is to view then that database as kanban style so there'll be the state, like, these are to-do tasks, and these are tasks that are in progress, and these are tasks that are done. You can kind of drag the cards in between, like, "Ooh, I got this task. I'm going to drag it over. I'm going to attach myself to it. I'm going to attach this PR to it. I'm going to estimate that it's three days," and all this.

Notion Projects has a bunch of extra features that help with that. For one thing, you can flesh out the tasks with AI stuff, which can be useful for brainstorming. You can view it as a timeline and say, "Ooh, this task has to happen before this task. When this is done, it leads into this one."

Really great for project management, so thanks so much to Notion. Do your most efficient work with Notion Projects.

You can try it for free today at (all lower case letters). When you use our link, you're supporting the show. Go right now to

[Banjo music stops]


Chris: Now I just have a list of, like, CSS things. What do I find weird about CSS that these two geniuses can tell me about? Display value of a list item is not display block or display inline.

Eric: No.

Chris: It's display list item.

Eric: Yep.

Chris: I never got it. Why? [Laughter] What does that matter? Why isn't it block? Who cares. It's block with a marker.

Eric: Right, but that's the thing. Do blocks generate markers?

Chris: I guess not, right.

Eric: But list items do - by default.

Chris: By default.

Eric: Historically. So, we are now getting to the point where--

Chris: But a user style sheet would just be like LI marker.

Eric: Well, now, yes. But when the display property was defined and those values were defined (in the late 1990s, so in the previous millennium). [Laughter]

Dave: [Laughter] It's old tech. [Laughter]

Eric: There was no marker, so when they were writing it down, they were like, "Okay. We have inline boxes, and we have block boxes, and we have none boxes if we want to make things go away." Somebody must have said, "Yeah, but list items. They have this thing hanging off of them, and we have no way to describe that."

Chris: Yeah.

Eric: And so, they--

Chris: That probably is what it was.

Eric: They put that in there. Yeah. We are now getting to the point with the marker pseudo (and stuff like that) that you could hypothetically--

Dave: It could be block with market.

Chris: I bet a lot of DOMs are littered with that, like lists that, if there's any JavaScript involved that kind of hides and shows them, that whatever framework is doing it sets it to display block to show it, which would have no visual consequences. If one of your list items of ten is block, who cares?

Eric: Yeah. The other thing you could argue about list items having a special list item display is that ordered list items trigger counting whereas unordered do not.

Chris: Hmm...

Eric: Again, now we have counters in CSS. But at the time, we did not, like when those values were defined.

Estelle: There's also the accessibility feature--

Eric: Yeah.

Estelle: --because if it's display list item--

Chris: Yeah, it's counted.

Estelle: --you need to be careful when changing the display properties of elements because if you do a table and then you say it to display grid, then it can lose its roles for the screen reader.

Eric: Right.

Estelle: If you don't know who is going to be messing with your table, you might actually want to put redundantly ARIA roles of ARIA role table, ARIA role or just role. It's not ARIA role. Role equals table cell, table row, table because you don't want to lose it if someone turns it into a grid.

Eric: Yeah.

Dave: I think we... This is my newest CSS hot take is we need new table styling rules or allow grid without stomping everything.

Estelle: What chapter is that, Eric?

Eric: Yeah, there actually is an entire chapter. Is it chapter 14 this time around? I forgot. There's a whole chapter on table layout and table styling, and I don't remember. It is in fact chapter 13. It was 14 in a previous edition.


Estelle: If we want to change the topic to ChatGPT, someone asked a question the other day. They basically started off the question without talking about ChatGPT and said, "Class is not supported on column. But it doesn't say it any place in the MDN documents."

Chris: Really?!

Estelle: No!

Chris: Class?

Estelle: No.

Eric: Not the case.

Estelle: ChatGPT told him this information.

Chris: Oh...

Estelle: And so, they went to confirm, and MDN... I write for... I work for Open Web Docs, so we write content that's displayed on MDN. It doesn't say that it's not support because it is supported. But we also don't explicitly say it's supported because--

Chris: Yeah.

Estelle: --class is a global attribute supported everywhere.

Chris: It's supported on everything. Yeah.

Estelle: So, when you use ChatGPT, realize that it's wrong. And don't ask us questions about it.

Eric: [Laughter]

Estelle: Just read our book.

Chris: I won't.

Eric: [Laughter]

Dave: No. That's a... Call is one of those ones I just don't use because I just know I am in "I F'd it up territory." You know? [Laughter]

Chris: Yeah.

Dave: I really biffed up the table. Yeah.

Chris: That is a weird, weird property because it doesn't actually wrap because it can't. It just isn't possible.

Estelle: No, no, call the element.

Dave: Yeah, call the element.

Eric: Yeah.

Chris: Yeah, I know, but it doesn't wrap the table cells that it's in, right? It just somehow magically styles the stuff below it.

Estelle: It's behind everything, so anything you style is on top of it. So, you can give it styles. There are a limited number of styles that you can put on it.

Chris: Right. Right.

Estelle: But anything else overrides--

Chris: But you can't go, like, call hover background yellow because you'd never hover it. It's not a hoverable thing. You know? That's what always confused me.

Estelle: Yeah.

Dave: Like call width and stuff like that? Is that sort of what it was made for?

Estelle: Call width and background color as well because you used to not be able to automatically. We didn't have Nth of type even, so you couldn't just stripe tables.

Dave: Mm-hmm.

Estelle: You would--

Dave: Call or--

Chris: Hmm...

Estelle: It's actually kind of good because you never know if you're going to have multiple cells merged together, so you can actually make a column a background color, and then you don't have to make the fourth cell of each row a background.

Chris: It's making me think because the trick was, like, you could always do row highlighting.

Eric: Mm-hmm.

Chris: That's no problem. TR hover.

Eric: Because there's an element there.

Chris: We couldn't do column hover. Right. But I wonder if now that we have :has(), could you do column highlighting with :has() now? I bet you can.

Eric: Probably.

Estelle: You can.

Eric: Yeah.

Chris: Ooh...

Eric: Almost certainly.

Chris: I wish I had a CSS blog. I would totally write that.

Estelle: When I want to color a column, I actually do TD Nth last of type three, so it's the third to the last column because usually your merging is on the first and second cell in a row.

Chris: Whoa, whoa, whoa.

Estelle: So, you do it from the Nth because usually you don't have merging towards the end.

Chris: Whoa. You're blowing my mind. How does that work?


Eric: Since you mentioned :has(), now you could use :has() to do it so that whatever cell you're over, it highlights the row to the left and the column above that cell.

Dave: Wow.

Chris: Right.

Eric: Right? It's sort of like a connector. You use :has() and it... Okay.

Dave: Like :has() hover or something?

Chris: Did we just nerd snipe Eric?

Dave: Uh-oh.

Chris: Right it.

Eric: I got--

Estelle: Totally nerd sniped both of us. We're both doing it.


Estelle: Let's open a CodePen. Can we stop this ... video?

Chris: I want to do the ... before and after, so it shows cross-hatch. You know?

Estelle: Can we break this interview, go to a CodePen, and come back? [Laughter]

Dave: Yeah. We'll do the 30 minutes later...

Estelle: Yeah.

Chris: Yeah.


Dave: With some interlude music, Chris Enns. We'll just pop that in here, and we've all been on CodePen for 30 minutes. And we're back.


Chris: I already did it once this episode. I will tell you that if you set a random list item to block in the middle of a list, it does have bad implications, so please don't do that. [Laughter]

I thought it wouldn't, somehow. I was wrong.

Eric: Surprise!

Dave: It skips the number, though?

Chris: It skips the number.

Dave: What?!

Chris: Yeah. If you have five list items -- one, two, three, four, five -- and you set the third one to display block, it goes one, two, nothing, three, four. It's really weird.

Dave: Now I'm mad.

Estelle: Because it's not a list item. It's no longer a list item.

Dave: Yeah.

Chris: Yeah.

Dave: It makes sense, but I'm mad.

Chris: [Laughter]

Eric: You know what? There's so much in CSS, at some point we go, "That 100% makes sense, and I'm really furious about it."


Eric: It would be easier if it didn't make sense. I'm mad because I can't criticize that it does this because it makes sense.

Chris: Totally.

Dave: Damn it. Even at the basic level where you say, like, "A color red," and then "A color purple," and it changes it to purple. You're like, "What?! I wanted it in red." But no.

Eric: But not with cascade layers. You can put each one in a different layer and then mess around with it.

Estelle: Yeah, but if you put revert, it'll go back to black because it'll go to the previous origin.

Eric: That's true. That's true.

Estelle: And not the previous layer.

Chris: That's so new. I wonder if that will be one of the... I don't want to incite anything, but two, three years from now when nesting has really settled in and cascade layers, is there any chance that some of those features, people are going to be like, "Ooh... Eh... I don't know"?

Eric: Oh, there's always the chance.

Dave: Initial unset auto, none, and revert: what do you use? Is there an order of operations for those, like PEMDAS or something?

Eric: Oh, crap. There is, and I've forgotten it.

Estelle: I tend to not use those, and I just try to use really low specificity and then overwrite stuff because it's easier to remember... because usually when you want to revert, you really just want to unset it from the current and do whatever its parent was.


Chris: What always got me is there is not one that's like pretend like I didn't do anything but still inherit from just one level up - or whatever. There's not one for that.

Estelle: That's what revert layers kind of does.

Chris: Oh, revert layer?

Eric: Supposedly, yeah.

Chris: Uh... Another one, Dave!

Dave: I know.

Chris: Just make sure.

Eric: There is absolutely the chance that we will look back on cascade layers as the next CSS app cache.

Dave: Well...

Chris: Yeah.

Estelle: I don't--

Eric: Or not.

Estelle: I don't actually think so because it's fantastic.

Eric: Yeah, it's fantastic.

Estelle: App cache was not fantastic.

Eric: Okay. Fair enough.

Chris: [Laughter]

Eric: But you know we--

Estelle: I use layers all the time in my CodePens.

Chris: Yeah.

Estelle: I'll write a ten-line CSS of CodePen, and I'll use a layer because I want my setup to come after so that people can see what I'm actually trying to teach. I start by creating this layer, and then I put the layer down at the end, which is the setup for the page. That way the first five lines, the first ones layer, but the next five lines, this is the important stuff that I want to show you.

Chris: Yeah. You've demoted it even though it's later in the CSS.

Estelle: Yeah.

Chris: That's kind of--

Eric: Right because cascade layers take lower precedence than styles that are not in layers.

Estelle: Yep.

Chris: Right. That was a wild twist for me, but I get it. It's cool.

Eric: Exactly. In fact, that was one of those--

Chris: That's a furious one.

Eric: Yes.

Chris: That's a perfect one.

Eric: Exactly.

Chris: Yeah.

Eric: When I realized, I was like, "Ugh! I hate this." But what I hate more is that it makes sense.

Chris: Well, because we're like, "Oh, this is your way out of important." You're like, "Oh, that's cool. I won't have to use important more because this layer thing gets me out of having to use important."

You're like, "Oh, but just kidding. It's actually less important if you layer something." I know that's not a right-on analogy, but go on, Estelle.

Estelle: I actually write what the layers are and announce them originally just so that the user knows that there's a layer so that they're not confused because they're not going to scroll down.

Chris: Hmm...

Estelle: They're not going to be like, "Wait, why is this--?"

Chris: That feels like a total best practice to me because you know you don't have to do your named layers, but you probably should. Just like I think with container queries. You should probably name the container, I think, just as a super-general best practice.

Eric: It seems like a good idea.

Estelle: You just want to make life easier for the future developer, which is usually yourself.

Eric: Yeah. Seriously.


Chris: I feel like there was an old Estelle opinion -- just to switch gears a little bit -- where you were a little anti-shorthand anything. Maybe shorthand just shouldn't even exist in CSS because there's so much thoughtless resetting.

Estelle: Yeah. It was mostly for the background property. I was very much against using the background property.

Chris: Just that one?

Estelle: But I also have never used the font shorthand.

Chris: Yeah. That one is really hard to remember with the slash and stuff and which thing needs to be first.

Dave: Oh, not me. I just plop them all in there, man.

Eric: Same.

Chris: [Laughter]

Dave: Let God sort it out. You know? Just--

Chris: [Laughter]

Dave: [Laughter] Just blasting.

Eric: Jamming them out, baby.

Dave: Single animation, too. Oh, man. If there's an order, I don't know it.

Eric: [Laughter]

Dave: I've never learned it in my whole life.

Eric: Let the browser figure it out.

Estelle: But I'm strongly in support of shorthand for things like border-radius and border.

Eric: Hmm...

Chris: Oh, I suppose. Yeah, border. That would suck to not have a shorthand for it. Yeah, good point.

Estelle: But when it's doing tons of unrelated properties that you probably want to overwrite later on anyway, then write them all out. That's my take.

Eric: Yeah. Yeah, Dave and I are on the other side of this one.

Dave: Yeah.

Estelle: You guys are wrong.

Dave: Points and counterpoint.

Eric: Yeah. That's fair enough.

Chris: Looking at border end end radius, and you just have to know that it means start and end, or whatever... ugh! Blah! [Laughter]

Dave: Hold on. Border end end radius spells beer, so that's maybe good, right?


Estelle: Now there are logical properties, so if we're actually not going to use shorthand for border, you would be like... I can't even remember them.

Eric: Yeah, and I will say that is a place where my practice has changed in the last year or so because, for like margins and padding, I'm almost exclusively using the logical properties. I'll do margin block whatever. I use margin line. Whatever values. The shorthand margin is not logical at this point, right?

Estelle: True.

Eric: If you say margin 1M, 2M, you're saying the top and bottom are 1M and the right and left are 2M. There isn't a way for me to say, like, logical margin 1M, 2M.

Chris: Right.

Eric: That means block then inline. So, I'm actually typing a little more because I do margin block.

Chris: And margin inline?

Eric: I mean if it's the same, like if it's just a 1M margin all the way around, then I just say margin because it doesn't really matter.

Estelle: I am not a designer. Therefore, everything is always the same all around.

Eric: There you go. Margin zero. Anyway--

Chris: [Laughter] Yeah.


Estelle: I do have... There is another kick I'm on since I do a lot of open-source documentation, and so there are a lot of examples. I really insist that people use outline instead of border for stuff because people will be like, "Border three pixels, red dash, and then border five pixels, green solid," because they want to show the difference. It's like, "Well, you just repainted the page when you switch those two." If you use outline, you're not doing a repaint and reflow.

Eric: Yeah.

Dave: I've used outline in the wrong ways just to draw grid lines and things like that. It's a pretty useful little tool.

Eric: Yeah. Yep. It really is.

Estelle: If you're teaching people how to do stuff, don't use box model properties is basically the--

Eric: [Laughter] Yeah. Don't use stuff that will change the layout.

Dave: Yeah. That's smart.

Eric: Yeah, outline of a border. Yeah, all my diagnostic styles for years and years now have been instead of border 1PX - whatever - it's outline 1PX - whatever.


Estelle: Do you want some really useless trivia?

Dave: Yeah.

Eric: Heck, yeah, 100%.

Estelle: Line style.

Chris: Line style.

Estelle: Line style, which is a value type, is the same for the column gap, the column rule, and for borders, but it is different. Outline does not use line style because outline has the value of auto, and outline does not have value hidden. So, that is useless trivia that I did not realize.

Eric: Yeah.

Estelle: Or put together in my brain. Twenty-plus-years of doing this stuff, it never occurred to me that they were not exactly the same.

Eric: Yep. They're very, very similar.

Estelle: Yeah. Useless trivia. Yep. Very similar but yet so different.

Eric: So different.

Estelle: Then there was a PR to MDN content where someone was explaining that we had done inset versus outset incorrectly. And I am like, "I am not a designer. I'm looking at these two things, and I know they're different, and I just can't explain it, so can some designer correct this and make sure that this is okay?"

It's obvious what the difference is, but I'm like, "Eh..." so--

Eric: There you go.

Estelle: I bet that sounds... is going to sound really good on the recording.

Chris: This is fun to dig into these weird things, but all of this stuff... You can't go a page or two in this book without being like, "Really?!"


Chris: That's weird. Even if you've used the language a lot. And this stuff, it can come up. Once you know it, then it comes up. The kind of thing where - whatever - hear a word for the first time and then two people say it that day. I'm like, "Is that a coincidence or is that just because of how my brain works?"

I wouldn't doubt that people listening to this show, something weird comes up that was related to one of these esoteric things that we're talking about. Anyway, just buy the book.

Estelle: That's like people who learned a language based on reading rather than listening. They read the English language and it's "chows" instead of chaos.

Eric: Yeah.

Dave: Oh, yeah.

Chris: Ah... [Laughter]

Eric: You do not want to know what I did to the word "detritus" for so many years.


Dave: Dee-troit-ers? [Laughter]

Eric: Dee-tra-tus.

Dave: Oh, yeah.

Eric: Stuff like that. Yeah. Then someone finally pronounced it in my presence. I was like, "Oh... right. That makes sense."

Dave: I spelled segue like the vehicle for about--

Estelle: [Laughter] Yeah.

Dave: Until I was 35 - or something, so that was embarrassing.

Estelle: And you're 34 right now?

Chris: I don't think the word "yacht" is possible to spell. I just can't get it. Colonel, too, that's impossible. [Laughter]

Dave: Yached.


Chris: There's case sensitivity stuff in CSS, right? I was just messing with that. If you write Nth child and are absolutely arbitrarily capitalizing the N's, C's, and whatever, CSS doesn't care. The actual selector is case-insensitive.

Estelle: No, wait. This is the worst.

Chris: Is it?

Estelle: I went down a rabbit hole just like a week ago.

Chris: About case sensitivity?

Estelle: In attribute selectors. The spec says if the language says that the case doesn't matter, therefore the attribute doesn't matter. Therefore, you would think that a numerated value in CSS, the case doesn't matter.

If you do an attribute selector and its input, its type equals... If you do type, then that is... No matter... It's completely case-insensitive. Even if you do type on an ordered list or unordered list, it's supported and enforce case insensitive. But if you do type on a paragraph, it's also case insensitive because even though type is not on a paragraph, it is an HTML attribute.

But it's like, why is that there? But then you have enumerated values like content editable. We think it's bullion. Content editable is either true or false. But it actually now has three values, so it's enumerated.

Eric: Hmm...

Estelle: But it's case sensitive. Why? So, they changed the spec, the WG spec, and they actually have a list somewhere. It's linked to from the MDN page on attribute selectors of which attributes are case insensitive.

It's no longer logical. That is my app cache.

Eric: There you go.

Estelle: Attribute selector case sensitivity is my app cache of CSS. I finally figured out what my app cache was.

Eric: Yeah.

Estelle: Yes, that was a rabbit hole. I spent like a full day and a half researching this minutia so that I could bring it to you.

Chris: You can make an attribute selector case insensitive with a little i thingy right at the end of the thing.

Estelle: Yes.

Chris: That's kind of good. But it has nothing to do with what's actually in the HTML either. Let's say, in the HTML, you wrote input type CHECKBOX (all caps). Then in the CSS, it doesn't matter. It could be all lower case. It could be all upper case. It doesn't matter.

Estelle: Because it's one of the attributes where it's case insensitive, so there's a list of attributes where it's case insensitive. It's no longer logical.

Chris: Oh...

Estelle: It used to be... My understanding of it was, if it was an enumerated value, then it was case insensitive even if it was not a valid enumerated value. So, if you put type equals foobar, that was case insensitive because the HTML was case insensitive.

But you have enumerated values like content editable where it's case sensitive, and I'm kind of like, "Why?" And it's because someone put it in the spec.

Estelle: Therefore, we all have to live with it.

Dave: I think it's all pretty easy. It's like every fifth Tuesday is case insensitive day in CSS, and every third flurps day is case sensitive day.

Eric: Yeah.

Dave: I think you just--

Eric: Except in Smarch.

Dave: Yeah, except in Smarch and odd Wednesdays.

Eric: It's all inverted.

Dave: But it's... Yeah, but we all get that. Yeah. [Laughter]


Eric: Yeah, and this is one of the things that Estelle and I ran into on the book that Estelle runs into at MDN that all of us run into whether we realize it or not is that CSS does not exist in a vacuum and some of the things that really... Some of those things that make us furious sometimes are because, like, "HTML says something, therefore this is how you have to act in CSS," which can be really, really frustrating.

Or SVG, if you're trying to style your SVG because of the way SVG is structured, and the way that the separation of concerns is set up. There are only certain things you can do, even though it seems like you should be able to do more. Right? That just happens.

We can't cover all of that in the book. We did not have room to go into all of the weirdness of other languages that affect CSS. We mention it here and there, but that is still a thing that happens.

Dave: You almost need CSS, the war stories. [Laughter] A supplemental story that's just about, like, "Hey, here--"

Estelle: What we didn't put in the book.

Eric: Yeah.

Dave: Yeah. "You won't believe this, but this can happen."

Eric: Chapter seven will shock you. [Laughter]

Chris: Yeah. Tables can overflow for no reason.

Estelle: It would actually be called, like, Do Not Buy This CSS: The rest of the definitive guide.

Eric: CSS: The Worst Parts.

Estelle: Yeah.

Dave: The worst parts.

Chris: [Laughter]

Dave: That's good.


Estelle: I went down a name-spacing rabbit hole the other day, as one does.

Chris: Name spacing?

Estelle: Yes.

Eric: Yeah, that's always fun.

Estelle: In CSS, it's not even in the list of combinators in the selectors, but there's a single pipe is a name space separator.

Chris: Yeah. Okay.

Estelle: It's not a combinator, but I listed it on MDN as a combinator because that's the way it behaves. What becomes before it is the name space. You can either put the name of the name space, put nothing, or put--

Chris: What?!

Estelle: Or put an asterisk....

Chris: Is it like an attribute selector with a pipe equals? You mean that kind of thing?

Estelle: it behaves like a combinator.

Eric: Sort of.

Estelle: But it only works in front of--

Chris: Oh, in the middle of a selector.

Estelle: Yeah.

Chris: Oh, weird.

Estelle: It only works on the type selector and the global selector. It doesn't work on any other type of selector, so not on attribute selectors or anything like that. And so, if you have an A-tag in an SVG or an XML, you can style you’re A's from that name space different than from the HTML name space.

Chris: Oh... really?

Eric: Right.

Estelle: Yes. But only global selectors and type selectors. So, if you really want useless CSS trivia, that would be one of them.

Chris: You mean a global selector like star?

Estelle: With star. The universal selector. Yeah.

Chris: You can go *pipe.

Estelle: Yes.

Chris: That's valid two characters in CSS? [Laughter]

Estelle: Yeah, you could do *pipe and then do... But I don't know what... It would just be... Because the global selector--

Dave: Ink or something.

Estelle: Universal selector would be... assume to be there, but that means any name space. If you put just a pipe with nothing, no name, or not asterisk in front of it, that means any element that is not in a name space. But how do you get an element that's not in a name space?

Chris: Wow!

Estelle: You use JavaScript to create the element using create element, capital NS, which means the name space.

Chris: Ooh... That's rife for some weird hacks.

Estelle: Then you can provide a name space or you can just leave an empty string. Then it's the null name space, so it means it's not a name space.

Eric: [Laughter]

Estelle: Then you can style stuff that's not a name space, which makes no sense to me. But that is why all of the create element functions, all of those have an NS because there are all these ways of creating elements inside a specific name space.

Dave: Mm-hmm.

Chris: Wee!

Dave: Wow.

Estelle: And for more useless trivia, HTML, SVG, MathML, and XML all have a specific name space. Like it's a default name space. But other... But you can create your own name space for anything else, but you can't overwrite. If I understand correctly, you can't overwrite those four name spaces.

You can give anything a fake name space, but they also are in the HTML name space. Even if you don't declare an HTML name space. So, if you don't put your doc type with a name space in there or if you don't put a name space in your SVG, it's still in that name space.

I just put all of your listeners to sleep.

Dave: That's... This is fascinating. I didn't know this existed.

Chris: People might know about it because when you make SVG in JavaScript, you have to declare the name space for some reason. I think that's where I see it the most.

Estelle: Okay. I have never created SVG in JavaScript, so I'm like, "Why is this name space important?"

Chris: What are you doing on Monday morning?

Estelle: I'm like, "I don't even know why it's here."

Chris: Yeah.

Eric: Yeah. [Laughter]

Estelle: Yeah. [Laughter]

Eric: Are you even really living?


Eric: If you're not doing that.

Dave: Unless you're hand-creating your paths with JavaScript, is it really--?

Estelle: Oh, just so you know, I handwrite my SVG because I don't know how to use the image editing applications.

Dave: [Laughter]

Chris: Yeah.

Dave: Perfect.

Eric: Yeah.


Chris: But I do know about cursors. Why can't you select--? With attribute selectors, you're kind of selecting content out of the HTML. You know? But why can't you just be like - whatever - "P contains Eric" and have it select based on the text content of a node? It seems like a weird omission.

Eric: It's been proposed more than once.

Estelle: Can you imagine how slow that would be to process?

Eric: Yeah.

Chris: Yeah. Some giant HTML document.

Eric: Right. Everything in CSS... Well, everything on the Web, like every Web feature -- it doesn't matter what it is (since CSS is nothing but Web features) -- every Web feature has to not grind browsers to below 60 frames per second. I actually blogged about this about a month ago.

Dave: Yeah. The first-person scroller.

Eric: First person scrollers, yeah. Things like :has(), which is effectively... Well, it's an arbitrary ancestor selector, so it functions as a parent selector but way more than that. But there was never any confusion among implementers as to how you could identify the ancestor of a different element and select it and then do operations based on that. Nobody had figured out how to do it so that browsers wouldn't grind to a halt.

Dave: Hmm...

Eric: Right?

Chris: Right.

Eric: That was the barrier.

Chris: So, it wasn't that it was impossible. It was that it was slow. Yeah.

Eric: Right.

Chris: Fair enough.

Eric: Eventually, actually, Igalia, who I work for, was hired to do some prototyping of, is there a way to make this :has() a pseudo class work performantly? Byungwoo Lee, who works at Igalia, came up with a prototype that we're not going to get into the details because I would get half of them wrong and, boy, talk about putting your listeners to sleep.

Estelle: But it is really cool.

Eric: It's very cool, but he figured out how to do it performantly. Right? Then announced intent to ship. And once that path was open, the WebKit team jumped on it and actually shipped a :has() implementation before it got out from behind the experimental flag in Chromium.

Chris: Hmm...

Eric: Then the team at Mozilla was able to at least partially follow that same path. They don't have the full... The last I checked, they didn't have the full complement of things you could do with :has(), but they had basics.

Chris: Is that because this guy was cool about the basic gist of how it was cracked? Does he put out a white paper that's like, "If you drive your DeLorean at 88 miles an hour," or whatever "then it worked"?

Estelle: [Laughter]

Eric: Did some talks. Talked within working groups. Talked with colleagues. And once there was intent to ship in Chrome and it was behind the experimental flag, all that code, that's all open-source, so other people could look at it.

Chris: Yeah.

Eric: Once he identified, "Here is how you do it," like, "Here is how you set these cache flags."

Chris: Yeah, right.

Eric: Again, I'm not going to go into the details, but once you do this thing, it actually becomes very performant. And other people, like someone in the WebKit team, tried it out and discovered, "Wow, yeah, this is really performant. We could actually ship this." And it shipped real fast. Right?

Dave: Yeah. Within a couple of years, right? Or months?

Eric: Well, yeah. It dropped within a couple of months. He'd been working on it longer than that. There was more of a ramp-up time, but yeah. That had always been the barrier was the performance.

You might imagine things like, "Ooh, I've got this idea for this animation type that makes the whole page swirl around the other direction," in Australia, obviously, but it makes it all swirl around. And if that's going to drop the standard frame rate of browsers below somewhere around 60 frames a second, implementers are just going to say, "Cool idea. No. We're not doing it."

Chris: [Laughter]

Eric: "Feel free to write the code and submit the patch. We will not land it in the public tree. Forget it."


Estelle: I did come up with a solution as to if a paragraph has the word "Eric," then make the paragraph pink. You would basically do an attribute selector that says... does the word... So, it would be the attribute name, star equals Eric, so was it anywhere, or you could do, is it tilde Eric... equals Eric with an I, case insensitive because there might be a typo.

Dave: [Laughter]

Estelle: And so, with JavaScript, you take the content of the element, you put it into a data words, and then you just do data-words.

Eric: There you go.

Estelle: Then you have it.

Eric: Estelle solves it all.

Dave: It's like you solved transcript, rich transcripts right there. Just put people's little face next to the transcript.

Estelle: That would be... That would actually be... Yeah.

Eric: That would work. The question is, how performant would it be? And if you want to know how performant it is, you have to run it against the HTML specification single page version, which is fricken' enormous.

Dave: Yeah.

Estelle: That thing is already too slow to render.

Chris: Really? Oh... Oh, yeah.

Estelle: Yeah.

Chris: Yeah, yeah, yeah. I've seen that. Wasn't that - whatever? It became famous in my mind when Jake Archibald was showing that content visibility hidden - or whatever - where the browser sucks at rendering that page. But if you take the whole bottom 92% of it and don't render it, it's quite fast. Whatever.

Estelle: Yep. That page is the page that slows down my laptop and churns my battery.

Eric: Mm-hmm. Yeah. It's huge.

Dave: So much HTML.

Eric: Yeah. It's a whole lot of HTML with a whole lot of under-the-hood HTML that you don't really see because there are all these spans with classes, and they have to be styled. Yadda-yadda-yadda.

Estelle: And because they list things like which ones are case insensitive for the attribute selector, if they just made it enumerated, then we wouldn't have to have that list, and then it would be shorter.

Eric: There you go.

Dave: Mm-hmm.

Estelle: I think they should take care of that for me.

Eric: Yeah.

Estelle: Get rid of my app cache.

Eric: Big time.

Estelle: I like to bring the whole conversation around.

Eric: Yeah! [Laughter]

Dave: That's good.

Eric: Back to app cache all the time.


Dave: CSS is really hot this year. In the last year, too. Right?

Chris: So hot.

Dave: It's going places. And I do feel like it's finally getting some respect - I don't know - after ten years of JavaScript-heavy news. It's finally like CSS is turning some heads because - I don't know. Container queries, :has(), all this stuff is mega huge.

Estelle: Is that just the circles that we actually socialize in, or is it the dude-bros who do React actually appreciating CSS?

Chris: I think so.

Dave: I see dude-bros starting to be like, "Whoa! That's actually way more useful." But in my Twitterverse, too.

Eric: [Laughter]

Dave: But I guess for somebody who is getting into CSS or starting out or somebody new to programming, what do they need to know about CSS? What's the fundamental concept they need to grasp? Then how do they get as good as y'all?

If I have a CSS question, I ask you two because you will probably know... or maybe Chris, too, because he used to have a blog.


Dave: But who? If somebody is starting out, what do they need to know about CSS to appreciate it, I guess, and then how do they get really good at it?


Estelle: I think, to get really good at it, the important thing to understand is selectors, the cascade, and specificity. It's that boring stuff. It's boring when you think it's boring.

I do a talk on CSS selectors. You can look it up on YouTube. It is the longest talk ever at SFHTML5.

Chris: [Laughter]

Estelle: But you're kind of mind-blown because you can do so much. So, 99% of people who say they don't like CSS because it's too easy and too basic, they know class selectors, element selectors, and ID selectors, and that is their repertoire.

You can actually... You need to be able to target any element, and you can target any element based on where it is in the page, what its ancestors are, what its descendants are. It's so incredibly powerful.

To get really good at it and to really love it, you have to grind through that selectors, and it's not really grind if you're excited about it. That's why the 2.5 talk is, I think, worth a view because it's actually exciting.

I teach you how to do a flag, the U.S. flag, using a table in reverse order. Completely useless, but you understand how powerful selectors are.

Eric: Yeah.

Estelle: If you really want to be good at CSS for a layout, you need to know grid and flex, and you don't need to know everything it does. The hardest thing to learn probably, and to grok, is the box model. I think that's everyone's bane.

Chris: It's gotten a little easier lately, maybe.

Estelle: Yeah. But that's not fun and it's not exciting. But it impacts everything. Selectors, it sounds boring but it's actually really, really fun because it shows you the power of CSS. If you want to get hired, know how to create a grid because that's what they're going to test you on. They're not going to test you on... Well, they might test you on styling a table, like doing the rows in different colors.

Chris: Oh, yeah. Little zebra stuff. Yeah.


Eric: I'm going to agree with all of that. Actually, that's all pretty much the things I would have said, but I'll also add don't be scared of the cascade. There will be probably like articles and toots and frameworks that appear to be telling you the cascade is evil and you should stay away from it as much as possible. That's not at all the case.

The cascade is useful and powerful and you should not be afraid of it. It's right there in the name, right? Cascading style sheets.

If you find yourself caring... people telling you, "Oh, well, we have this thing that solves the cascade," you are going to probably see short-term gains and huge long-term penalties if you start going down that road.

Chris: Hmm... Spicy. I like it.

Estelle: I would actually recommend against using... I mean I've never used a framework, but I've never had to use a framework. I used to say that IE6 was my favorite browser because I made so much money fixing IE6 bugs.


Estelle: And then Bootstrap was my favorite framework because I got paid so much money to remove Bootstrap from websites.


Dave: This is so spicy. I love it. That's good.

Estelle: Don't be afraid of it, and don't think it's stupid. Realize it's super powerful. Once you dive into it, you'll learn to love it. And realize it can pretty much do everything, but you don't need to memorize anything because it's all documented.

If I was going to suggest some articles or books, I would definitely suggest our book. But for my job at Open Web Docs, I did write an article on important and an article on specificity and several articles on the cascade. They're all viewable on MDN, which is Just look for specificity or important or the cascade.

Eric: Yeah.

Chris: But I wonder. Embrace the cascade, okay, but does that mean kind of like anti-scoped, anti-component scoped styles?

Estelle: Not at all.

Chris: Not necessarily?

Eric: No. No.

Chris: No. Okay.

Estelle: I also wrote this thing, which was super fun, for - I think. It's all about styling in the Shadow DOM. It's an HTML. It's like learn HTML, but there are some pseudo-classes like if you use part, which is an attribute, on an HTML element within your template, and you say part, then you can actually access the Shadow DOM from outside the Shadow DOM to style using the part pseudo-element. It's part().

Eric: Yeah.

Chris: Yeah, part sucks. I'll take a stand on that one.

Eric: [Laughter] Spicy!

Estelle: Oh, I'm so excited about it.

Chris: No, it's anti-cascade. You can style a part and then it doesn't behave like the rest of CSS does. You're only laser beaming in on that one thing and nothing cascades from it. It's so strange to me.


Estelle: But it only works in the Shadow DOM anyway. It's basically away from the outside the Shadow DOM to target something inside the Shadow DOM but only if the person who created the Shadow DOM in the first place is saying, "I'm going to add this part attribute so you can style..."

Chris: You are responsible for building your own API for styling when a really nice API for styling already exists called CSS.

Dave: Eh... It's getting hot! The temperature! I'm sweating.

Estelle: Oh, yeah. We're fine.


Estelle: But basically, it allows... Because the Shadow DOM doesn't really... There's this wall, kind of like the brain to the body barrier - whatever that thing is called - and you can't get through.

Chris: Right.

Estelle: But you can get through, just like viruses can get through. I guess you're right. It is a virus.

Eric: [Laughter]

Dave: We call those bones. The brain to the body.


Dave: Those bones.

Chris: I know about the wall, but I always thought... Okay. I know there's a wall. The wall is there for a reason. I'm not saying tear down the wall. I'm saying give me a little passthrough status if I know what I'm doing. Where is "I know what I'm doing" mode?

Estelle: That's what part is.

Eric: That's what part is.

Estelle: Part is... Yeah.

Chris: But part requires me to... Let's say I want every single thing in this entire DOM to be styleable (like I would expect with CSS). I'd have to put a part name on every single DOM node up and down the whole thing.

Dave: You need part name. You need part name.

Chris: Because you can't say part... You can't say part and root part. Part is parent. Part is card. You can't say part and then space P. I want to select paragraphs in that part. You can't. You can't use part and then a selector after the part.

Estelle: But isn't that intentional because whoever created the--

Eric: Component.

Estelle: --component doesn't want you to do that.

Eric: Right.

Chris: Yeah, right. So, invent your own styling API.

Estelle: But there are inherited properties. There are inherited properties. So, if you're styling color, that is going to be inherited.

Chris: Yeah, right. It's not un-inheritable. I get that. Yeah.


Eric: I think what this tells us is the Shadow DOM sucks.

Dave: Hey!

Chris: It sucks. It's the worst.

Dave: I like it.

Chris: [Laughter]

Dave: If you think of it as baby webpages, it makes total sense. Okay. So, you're lasering into a different webpage. It's fricken'... That's pretty cool.

Eric: But you can't style it, so it sucks. Anyway... [Laughter]

Dave: Parts of it.

Eric: Yeah, I know.

Dave: You have to--

Eric: I know.

Dave: I think it is a major footgun. I will stand by we need a "I know what I'm doing" mode to pierce it.

Eric: [Laughter] Yeah.

Estelle: I'm kind of bummed that we don't have that Shadow DOM, like that moz-thumb that we were talking about earlier that is easily accessible because I would like to be able to style the ticks on the--

Chris: Yeah, right.

Estelle: --that are created by data lists.

Chris: That stuff should be specified, I think. That should be spec'd.

Estelle: But I'm also glad that people who don't know what they're doing aren't allowed to because you know what a designer would do ... and put all the little ticks as little elephants. You'd be on the range and ... five little elephants.

Chris: Oh, yeah. That's a slippery slope, though.

Estelle: Yeah.

Chris: It'd be like, "I don't think we should have background in CSS because somebody will put crazy background stripes where they shouldn't or something." You're like, well--

Dave: My lawn mower goes from turtle to rabbit, and I think that's how God intended. [Laughter]


Eric: Exactly. Yeah. Man, little elephants for the little tick marks. You're selling me on this idea. I'm going to be honest.


Eric: Now I want it.

Dave: It's getting better. Yeah. It's just getting better.

Eric: Don't threaten me with a good time. Gees.


Chris: Uh-oh.

Dave: Oh, man.

Chris: All right, well--

Dave: We maybe found the app cache. We're close. We're close. Eric, Estelle, thank you so much for coming on the ShopTalk Show. We really appreciate it. For people who aren't following you and giving you money, how can they do that?

Estelle: I work for an open-source collective that is nonprofit, and we actually love donations. If anyone wants to support the documentation that is MDN, go to There's a little donate button in the upper corner. Get your company to sponsor us. We have 4.5 full-time employees, and our only mandate is to create open-source documentation about Web technologies.

Dave: Hey, and I bet your company looks really cool with the little logo down there. It'd be pretty cool.

Estelle: We have Carle. Carle is a bookworm. She has many different faces.

Eric: That's the logo.

Dave: Beautiful.

Estelle: The icon you see has a smiley face.

Eric: Yeah.

Estelle: But when we hear bad news, she has a--

Chris: Really?

Estelle: Yes.

Chris: It makes a sad face when trends rotate 180 degrees on that element?

Estelle: No, she has different little mouth expressions.

Dave: Text transform in Australia. [Laughter]

Estelle: Yes.


Chris: Full circle. That's the best.

Eric: Oh, my goodness.

Dave: Okay. Eric, how can people follow you and give you money?

Eric: Uh... Well, they could go to to find me. In the footer of that, there are links to my various social type thing. I've actually got to take the Twitter link off because I'm basically done with Twitter. But there's stuff there.

Giving money: If you really want to give me money, give it to a local food bank or other community organizations instead. That would be, I think, the best way to handle that particular impulse.

Dave: Great. There's also a book, a big book.

Eric: Big book.

Dave: That's going to break your mailman's back. [Laughter] Test the limits of the USPS.

Chris: Hell, yeah.

Estelle: I do have a comment about the book. If you take two books, it's the same height as a stair, so you have to buy two books to be able to use a ladder on a staircase.

Dave: Mm-hmm.

Eric: There you go.

Dave: Okay. So, two-pack.

Estelle: Yeah.

Dave: Order in twos. Wonderful. All right, well, thank you all so much for coming on the show. Thank you, 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. No. We don't really post there. Anyway... Join us in the D-d-d-d-discord, Chris, do you got anything else you'd like to say?

Chris: Oh...