Weird Things You Missed About CSS with Stephanie Eckles === [00:00:00] Hi there. And welcome to pod rocket, a web development podcast brought to you by log rocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. Try it for free at logrocket. com today. My name is Paul, and joined with us is Stephanie Eccles. She is a software engineer at Microsoft, author of Modern CSS, and there are so many more things that she has in her bio in the world of technology, and I'm sure you can go check them out. But today, we're going to be talking about her latest talk, Weird Things. Missed about CSS. Welcome back, Stephanie. Thank you so much. It's good to be back. What a title, Weird Things About CSS, because weird is subjective, right? So I'm very curious to ask you what weird in your world of CSS means. Before we do that, though, what got you into the world of web development? Why are you focusing on CSS? Are you passionate about CSS? Yeah. Great question. , I mean, I've [00:01:00] been doing professional web development for over 15 years now. So I've grown up with the web quite a bit in that time and use many different tools and systems and ways of working myself and with my. Different teams and when I joined a particular team where I was working with more than just the front end focused work, I realized there and kind of was looking to upskill myself in various areas. I realized we had this interesting gap in educational materials where, a lot of sites have really cool tutorials, but they're really focused on a precise thing, and it's not always a practical thing. , and so when I wanted to send articles to a coworker or something, I couldn't find what I really wanted to express, the technique that I was trying to get across. So I ended up making, demos, like in CodePen, et cetera, to share some of those ideas initially. And then. [00:02:00] I just started writing and it grew from there. So it happened to be a good time to get into writing about CSS. This was about in , mid to late 2019. And again, was already pretty familiar with it myself, but we've seen so much happen in the world of CSS in these last few years, just truly. Unprecedented is not a hyperbole anymore about what we're seeing in the world of CSS. That was gonna be my follow up question like do you feel like CSS has turned into a new beast sort of like I can see some tutorials on YouTube and people are doing things that you would reach for a state management library or something to Do you really feel like CSS is glossed over maybe sometimes in these functional areas? Yeah. So that actually ties us really nicely back to my talk because so if you haven't done conference speaking before folks out there you have to, when you're preparing a talk, come up with a little [00:03:00] bit of a quote unquote clickbait title, right? You want people to get interested in your session. So my title about weird things you missed about CSS was a Trojan horse to get people to come in so I could teach them, take them back and teach them some of the more fundamental concepts because As we've seen this growth in CSS, those fundamental concepts have gotten lost. And if you don't understand them, you're going to have a hard time with some of the newer features. So, to your point about , has it been glossed over? I think that In the light of being excited about the new shiny. Yes, it can be glossed over. And so I wanted to expose some of those fundamentals, bring them back into the light. So that you could troubleshoot more efficiently when you were trying to get down to brass tacks. And the other important thing to me is that these are techniques that it doesn't matter what framework you're using. It doesn't matter. I really want to make that clear. No matter what framework you're using, or if you're just writing CSS [00:04:00] yourself, the browser will interpret that CSS in the same way. So if you don't have a grasp on what's happening there, you're going to have a hard time with CSS no matter what other tools you have available to you. So maybe something that's weird. I'm really curious to see what's in that basket of things, maybe that we glossed over and maybe weird, like you said, it's a click baity title to get people to come into the talk. , but what is one of those weird features and why is it weird? so I think You know, when I was examining it and the different things I was bouncing around my mind, it really came back to extremely foundational concept of how does the browser even interpret CSS, because that is weird and that's usually a black box topic and it feels like you have to have this computer science degree to understand which I don't by the way and so. Even just discovering that, but also from there, it tips off into some other rendering [00:05:00] concepts is what I came around where that's usually what frustrates developers. So to me, weird is also those areas that usually frustrate developers the things most questions on Stack Overflow about, again, you're going to keep hearing me say this, but it's fundamental concept, but we usually skipped it or we learned it so long ago that we don't remember it. In time to help us solve a particular challenge. What's an example, if we could dig in really quick into one of these rendering things. So that feels shadowy and dark, right? What's a rendering thing that developers struggle with that you're like it's more simple than you think. Let's take a look at it. Yeah, I don't know about more simple than you think, but Okay. a minute, it definitely is one of those things that takes a minute to, like you have to spend time with it, you have to, like even just hearing me say it now, it's probably not going to come through if you're not familiar with it you just have to spend time with it, but, Particular section of my talk was around the concept of stacking context. Okay. So I'm just [00:06:00] curious if you happen to know what a stacking context is just like general research here. I do not know. Well, I know what the Z index is sure I've played with that, but have I used it tastefully and elegantly? Probably not. Yeah. So stacking context is if you think of your browser the browser within your screen we start way back at the viewport. And when we have a stacking context, we're talking about layers of DOM elements. You can think of those as coming out at you from the viewport, right? We're stacking from bottom to top DOM elements. And you mentioned already z index. That's usually the way that developers are going to be introduced to stacking context, even if they don't realize that's the term for what they're working with. But this concept of controlling the layering of DOM elements. And it happens in a few different ways. And z index doesn't even have to be involved.[00:07:00] As soon as you apply position, so position relative, position fixed, absolute, you have started to define a stacking context. So, if you don't use z index, then You're going to have the order of DOM elements, so you have a paragraph followed by another paragraph, followed by an unordered list. That unordered list is going to be stacked on top of the previous two paragraphs. That's what's meant by DOM order. And so if I apply position Relative to my unordered list, then I can apply like a top negative 20 pixels or something like that. And that's going to automatically, without my z index or anything, it's going to be visibly layered on top of those previous paragraphs. Alright, that's not a very practical... way we're going to use it, right? Generally speaking but it's good to know that DOM order does affect it at a base level. What gets [00:08:00] developers into a pickle is when you are trying to layer, say like a dialogue or a tool tip or sticky navigation, and you are trying to raise that element to the top of the window, but it's still getting overlapped by something else. So maybe I'm trying to raise up a dialogue, but for some reason my navigation is still overlapping that dialogue. That's a scenario I remember very early in my journey. Likewise. Yeah. Or little tool tips. Absolutely. exactly. And it's so frustrating. Now if you are working with a framework like react, and I'm not familiar with every single framework, I know react often libraries do this. They'll take that dialogue and they'll portal it out right to the end of the body. Now, the reason they're doing this is the problem in the first place is [00:09:00] that dialogue is. If you are experiencing that overlap, it's because it's in a nested stacking context that's different from the one that maybe that navigation is in. And so no matter how high you set that Z index of the dialogue, even if it's 999999999, it will never be able to rise above the navigation, perhaps. Perhaps because. They're just located in different stacking contexts and the fix for that, as I said, is either moving it outside, allowing those elements to share the same stacking context. But also another concept I wanted to bring into the talk is that we do have a more modern fix on the way for this, and that is the concept of the top layer. So. This is getting some buzz. If you've heard of the popover API, that's where you may have also heard a little bit about the top layer. It's unique [00:10:00] because it's not actually something controlled with CSS, but it's good to be aware of because it lets you escape this stacking context issue. So if you use the popover, which again is incoming, it's only in, I think, Chromium Actually, I think it is going to be in all the browsers, I just looked at this, as of Firefox 117, which ships in October. That's the tentative date, I believe, for Popover to land across our evergreen browsers. Another element that uses it is dialogue. So if you're using a dialogue, or you're creating a Popover, those elements, by default, are going to exist in the top layer. The top layer is unique because... Like I said, it is independent of stacking context. No matter what, it's going to be truly on top of anything else in the DOM. So first, it's good to understand what is a stacking context. Why is your IAZ index not working for you? And then, cool, great, we're going to have this new tool. a [00:11:00] popover is not going to be correct in every situation. Neither is a dialogue. And again, there's not a CSS way to send something to a top layer right now. But it's good to be aware of, keep on the horizon of possible solutions that are upcoming for some of these long standing, big, frustrating topics for developers. So if you were to take this tooltip or something and move it to the bottom of the page to put it in a new stacking context, it's surrounded by new HTML and stuff, which I assume creates this stacking context. Where and how are those lines drawn on your DOM? Are you referring to how that becomes connected back to the triggering element? Or? Or like, how does the browser interpret and build the contexts, the defining lines around these stacking contexts in your HTML and CSS that you throw out to the browser. So, anytime that you have a new positioned element, so using [00:12:00] the position property, you're using fixed and sticky combining absolute or relative with a z index There's a couple other scenarios that will create a new stacking context, one that might be surprising, and I anticipate being a new frustrating thing about stacking context is that assigning a container query containing element using container type that can create a new stacking context. Now, why is that problematic? Well... Again, if you're using top layer, you're going to escape this issue, but if you're not quite there yet, um, like if we think of a grid of cards and they have photos in them and you're trying to offer a contextual menu, like maybe you open a little menu, you can copy the image, favorite it, share it, those sorts of things. If I have a grid of those images and I've created each of those cards within a container, And maybe those cards, you know, are pretty [00:13:00] close together, especially if we go to mobile, they end up stacked and close together. And I try to open a menu and it's now going to run the risk of getting overlapped by the next card because of each card being in a container. And so again, we're back to that problem of even trying to give that little menu a super high Z index, if you leave it where it is connected to the. Dom within the card itself, it's not going to be able to escape and rise above that next card in the list. And again, that can be surprising. So that's a particular context that I want to start sharing with folks to watch out for. Because in a talk earlier this year, I was Yeah, let's create all grid items, whether that's CSS grid or Flexbox grids. Let's create all their grid items as containers because What could be the harm in that? That sounds great. I want containers everywhere. And then I ran into the scenario I just described myself and realized, [00:14:00] Oh dear, we're going to have to rethink this. And thank goodness that we're going to have popovers to come help us out of that situation. But, yeah, there's a couple other contexts. I totally encourage going to look those up. MDN is a great resource. , just look up stacking context because there's some weird things that can create a stacking context and you can only re layer items within the same stacking context. That's why we get that overlapping issue where you're not able to rise above. So that's your key concept, right? You can only re layer. Items within the same stacking context. And if we're going to hop into some other weird stuff that people might not be familiar with, such as calculated values, that's something when you go open your dev tools, you can be like, what's going on here. And I'd love to pick your brain about that stuff in a moment. Before we do, I want to remind our listeners. That this podcast is brought to you by LogRocket. So if you're in your web app and you have a weird stack in context, who knows? Maybe you [00:15:00] don't know that you have it. LogRocket can definitely help you identify and qualify those bugs. So you can spend less time in your debugger and more time in your code editor, building a great app. So they have tools so that you can find surface issues faster and just better heat maps. And all sorts of ways for you to target the problems in your app faster. Head over to logrocket. com today, check it out for free. So if we're talking about custom properties, like that's the thing you open dev tools and computed, custom properties, what is one of the biggest misconceptions that you find people run into when they're trying to debug something that's computed? Yeah. So again, I think that takes us back to not understanding because I don't know if we ever do a good job of teaching it, of what happens when the browser encounters a value and how that actually gets used in your final design. [00:16:00] So whether that's custom properties or just other assigned values Unless it's of absolute value, such as pixels, right? The browser totally understands what to do with pixels, but especially with responsive design, container queries, all these methods were encouraging less use of those absolute values and instead more use of relative values, things like percent or. Container query units, or you may have used viewport units, and when the browser encounters those, it has to do additional computation to what's called absolutize the values. So you may have said 80 view widths, but the browser is going to turn that into a pixel value based on the rest of the context after it's gone through and done all the rest of the computation of how the layout is coming together. And so that [00:17:00] can also happens of course, for custom properties, which are even more unique in that they first have to have your custom property name replaced by the intended value, and then that itself may have to be additionally transformed for the final value. So that double transform layer, I can imagine that adds a lot of bugs if you don't necessarily know what you're doing, because you have one changing of your value and another changing and this, am I wrong in saying that this could come through when I set something to 100 percent width and there's no width and there's some derivative computation that the browser has to do in between like my intended like taking up the whole screen and the fact that there's no parent defining something. Yeah, exactly. So, , we're probably going to be able to get eventually We could go down a rabbit hole on containment where that's going to break that. I'll leave that to the listener to look up, but, and maybe another one to think about that[00:18:00] you probably again just use and don't really think how it comes together is like M units. So we think of M as maybe . It's going to be a font size, relative value. Well, a technique that I enjoy, I've seen it in a lot of design systems. If you think of a button component, making your padding based on M's so that it's relative to the font size. That way, when you increase, you know, you can get a bigger button proportionally by just increasing the font size of the button. Since that M is going to be related to the font size. So if we have padding one M on our button, then. What happens is first the browser has to compute what is the value of an M for this element and then , re look at the padding and apply that value. So just that's, we think of it as really simple. All of this happens, within milliseconds usually. So we don't. Ever really see the impact of this [00:19:00] layering and compounding of uh, what's going on, which is a miracle, right? Kudos to browser engineers for making all this happen super efficiently for us. But yeah, so in a case of a custom property, so maybe we have a custom property. Which the format is, using the var function and then maybe it's dash button padding, right? So that's what we have is the value of the padding property. And then somewhere else, we may have assigned that padding to be the one M. So we first replace it with one M, and then the browser has to do that second, or maybe even third at that point, pass to say, okay, and then here's the value of that M, and we ultimately end up with a pixel absolutized value for that property, if the property is valid, the custom property. Are you personally a fan of custom properties? Do you feel like it offers good practice? Because there's a line that you can draw between how much you throw into the [00:20:00] CSS variability versus Insert state management library. Yeah, I think that I am a fan of custom properties. I think what you're hinting at is maybe where It's interesting because you can modify custom properties with JavaScript. You can modify anything with JavaScript. There's a whole CSS object model that you can tap into with JavaScript. Which is again, another rabbit trail. That's fun to explore. But for so, when I'm using custom properties there's, there's. In a few different methods or methodologies that have emerged, a huge one that we see is placing a bunch of custom properties on the root selector. The root selector in general use is going to be equivalent to HTML, but technically it is also applicable within an SVG, which it would then Be applicable to the SVG root element. Little fun bonus fact, and one of the issues that we see, if we're going to assign [00:21:00] everything to the root. That can trip you up and that I think is little known and another kind of weird thing that I went over in the talk is that those values that you place in root as particularly are going to be computed as soon as the browser finds them. So if you have maybe set up a color system based on HSL, and you've broken out your custom properties into the hue saturation and lightness. For a primary color, say, and then in the root, you also say primary color and you go ahead and combine those are consumed or computed immediately. What's the impact there? Well, the reason that's done is now that you're fully computed value for let's say that's color primary, that's now inheritable throughout your system. And often that's what we want, right? That's been done intentionally. But if you have a style later where you're like, oh, maybe you're making a dark [00:22:00] mode and you're like, okay, my color primary, the lightness needs to be increased. I need it to be a little bit brighter to work better with the contrast here. So just in my kind of dark mode styles later, I try to just pass in that lightness custom property and What might be unexpected is that's not going to do anything. It's not going to be able to change that previously computed value because the browser's already said,, I don't see a reason why this should change. I'm going to go ahead and say, based on the hue, saturation, and lightness that I have, this is the color purple. So we're going to continue to inherit purple throughout the system. And so, when we're talking about states or how we're going to scale and extend custom properties, that's a kind of weird concept to be aware of that can definitely catch you out. One solution to that particular issue is instead of computing everything in the root [00:23:00] to break those across and scope those more locally to the classes or elements where you actually intend to apply them. So if we instead, in that particular scenario, maybe we have our hue saturation lightness up in root, but we wait to combine it until later in the system. Like for the button component specifically. Then what's cool about that is we can define it on say a class button, and then maybe we have button secondary. And so we just in button secondary want to change the hue and maybe we can grab that hue from. A list that we've compiled in our root selector, but we're able to successfully change it now at the class level, because the browser says, okay, this element has both the button class and the button secondary class. And during this normal parse phase, it combines those classes, checks out and notices, okay, the final value needs to use both of these custom properties. [00:24:00] And it's able to correctly or at least correctly in terms of our own interpretation of what should happen, bring that together and give us that different color value. Hopefully that made sense. It's a little funny to say all this without any visuals. Yeah, the lack of visuals is an interesting challenge to get past. So if I may try to summarize here, you're saying that maybe we should leave the root for defining, not setting. I think that's a really good summary. I hadn't thought about that way, but I think, yeah, I think that's a good way to approach it initially. And think about bringing some of those values more, scope them to the context where they're actually applied. Yeah. gotcha. And just to round things out, because we're, we are getting close to time. So I'd like to throw in one last thing to pick your brain about Stephanie, if we could, about paint order. Because. Generally, CSS [00:25:00] Cascading Style Sheet, if you're a very basic color person like me, I'm like, it goes from top to bottom and that's the order it gets painted in. And I, I can understand why that might cause some issues. So in terms of paint order and how it takes these objects and actually throws them onto the screen, what are some tips that you might've found that people gloss over themselves? Yeah. So, we have two different things, right? We have rendering order, which is the browser, it's going through, it's making this Probably fairly large, in most cases, tree of possible matches for selectors, computing all that, doing the absolutizing of values that we talked about. And then, ultimately, when it gets to the paint phase, it's going to, just to really simplify it, it's going to start at the top left, and it's going to draw the box, draw the content, draw the children, and then recursively do this process so that it can place things and do the layout and the final paint to the screen. Which is cool. There's a video out there you can watch [00:26:00] about how that comes together, slowed down. But when we think about individual elements in the DOM. There's also a actual paint order and so this has to do with our really essential sort of box properties. So if we think about an element and if we're going to apply basically all the base box styles to it, the very first thing that gets painted, if it's available, is a box shadow. So this is going to be an, the outer box shadow. An interesting thing about box shadow is that it's painted beyond the perimeter of your border. So if you have a transparent element, you won't see the box shadow underneath within the box space. Next in the paint order will be background color followed by background image. And this can be useful to know if you're trying to apply certain image effects or you've ever wondered why you can't make the, image[00:27:00] It's interesting to know that. And then after background image is box shadow when it's inset. So moved inside of the element that's going to be layered above your box shadow. Next will be the border and then finally the outline. And so. Why are those important? Well, because when you are dealing with those different effects, it can be surprising to maybe have to have the border on top of your box shadow. Occasionally, that can cause an issue, especially if, as I said, the box shadow is painted outside the border. So if you actually are using a transparent border, by default, that box shadow is not going to appear in that space. You can try that sometime. So there'll be like a little line of absence. Oh, And so, that's can catch you out. The other interesting thing. So we live in a world where it's [00:28:00] inescapable that we're trying to make anything and everything clickable. And when you're using these box properties, another interesting feature that I don't think is well known is that when you're applying event listeners, so you have a button, you're adding a event listener for a click that click will not trigger on the box shadow. Or the outline. It has to be at least within the border space to be able to apply to the element. And usually that's going to be fine. However there was a time a few years ago so another thing I'm passionate about is accessibility, and so there's a technique that's somewhat popular of doing like double layered box shadows to emulate like a dark border and a light border, since you can only apply one true border at a time. And so it's good to be aware of the fact that box shadows cannot receive click events. Because if you're doing a chunky border with your [00:29:00] box shadow, a user may have to move further inside of the element to successfully click it. So, again, just weird little things that we don't see often, but can affect what you're doing and may be hard to troubleshoot. I feel like this list could be endless because this is a timeless piece of technology that has really been developed tooth and nail, right? Yes. yeah, so we are running up on time here, But gosh, like my mind is spinning about what I don't know now Stephanie, where do you gather some of your knowledge? I know you've been doing this your whole life, right? Obviously, there's a lot of this experience, but besides the MDN docs, which is the number one resource everybody would recommend, where do you find inspiration to dig into these things? Yeah. So, earlier I said I saw a gap of practical knowledge, but the thing is those tutorials are, that kind of go off and. So many directions and, really [00:30:00] might be really interactive or artful are definitely great places to at least be exposed to what is possible. And whenever you encounter something that seems interesting, seems outside the norm, jump into your dev tools and poke at it. Sometimes it can be, eyeopening in itself too, you might discover dev tools. But I would say, keeping an ear on, the different blogs out there various newsletters, and if you have availability, getting in and just trying things out, because that's really the only way most of these concepts will stick if you're not a tutorial person, which I'm not really a tutorial person, either, it's have yet to meet one. Yeah, I'll seek it out if I really, I just, mostly because I'm hard headed and I just want to try it myself. But so if you're not a tutorial person, really just [00:31:00] trying to get in and look at stuff and. Make use of DevTools is a good way to do it. If you're interested in what's coming out, what's new, I know you've had I think you just recently had Adam and Una from Chrome on the pod, but just following those various browser engineers every browser has release notes that are in pretty readable form, they, in a blog form. There's also, at least on the platform formerly known as Twitter, and also Mastodon, there's a little bot somebody does called Intent2Ship, and so that's a... really cool one where it tells you like Firefox is intending to ship or prototype whatever feature. So, if you really want cutting edge stuff, that's a good one to watch. Or if you're an RSS person, all the release notes pages, I believe have RSS too. So, but yeah, I always encourage people to learn. There's really no better way. And as you're learning testing things out, Make sure to get outside your browser comfort zone [00:32:00] and look in other browsers as well to make sure that what you're learning, how that is affected cross browser, cause that's still an important thing we need to be considerate of. Definitely still a very important thing that is continued and will continue to bite us. Stephanie, and if people wanted to hear about you, your writings, do you blog and do you have a YouTube channel or anything like that where people can hear more? Yeah, so my main place to find, especially if you're interested in these CSS topics is moderncss. dev. And by the time y'all release the podcast that the topic of custom properties and some other weird things about it, I'm going to have a new post about that if you're. Interested. I never did get into YouTube, but you can find my other, I have quite a few different developer resources and open source projects you can find at thinkdobecreate. com. I had to make that complicated. It's my legacy [00:33:00] domain. So it is what it is. It's a good form of security. Yeah, and I'm just generally around the web as 5t3ph. I did just double check. I did make 5t3ph. dev redirect to that. That might be easier to remember. Okay. Awesome. We can always throw those in the show notes. Well, Stephanie, thank you for your time. It's been a pleasure talking about some of these details that I certainly were, was not aware of in CSS and I'm sure will help a lot of people as they march forward creating their next app. Thank you for your time. Yep, thanks for letting me nerd out on CSS.