 Hi and welcome to the CSS Podcast. This season we're answering your most burning CSS questions and one of those often relates to relative units like percentages. Weirdly, percentages might actually mean different things when used in different contexts in CSS and you might be trying to use a width or a height percentage when there's no parent to even measure against. So to make percentages a little bit less confusing, we're dedicating today's episode to answering why a percentage value isn't working or isn't giving you a value that you expect. So classic with CSS, you're like why? Why? All right, well to kick things off about percentages, we have to talk about how it resolves differently based on where it's used. Just like you were saying like padding top 20% resolves to 20% of the parent element width, not the height. Font size resolves relative to the nearest defined font size, kind of like an M and transform translate resolves against the element itself, which is why it's so unique and handy. And those are just to name a few examples of where these mismatches might happen where you thought it was resolving against one thing and it resolves against something else. So we always do scenarios for these things because I think it's easier to like ground ourselves in these problems that we're having with percentages. And so this first scenario is like, this is one of the big stompers I see time and time again, is why isn't body height set to 100% filling the viewport? Why if I said body height 100% that's as soon as it's over. Yeah, and there's so many hacks and so many different ways people do it and I've seen some super clever ways to do it, clever good and clever bad. And now we have new viewport units and blah, blah, blah. And some of them have side effects and some of them don't. So anyway, the reason is it's because the document body isn't the first element. We like to think about it like it is, because that's where all of our content goes. But the body element is inside of another one. It's not the element that sets the size for the document. That's what the HTML element is for, or the root selector. So you can help body height 100% resolve to the viewport by setting height to 100% not min height or max height, but you set HTML height 100%. Now the document is the viewport. This is the crucial thing. It should be in your reset HTML height 100%. And this is a great starting style. Yeah, for normalizer reset, it's because now once the HTML size is 100%, I set the body's min height to 100% not a tight because otherwise you'd get some overflow issues or you'd get, you know, you don't want to fix the height of the body, you just want it minimally to be the height of the viewport. So this says be at least the size of the viewport because it's at least the size of the parent when the parent is got a firm size, the HTML in this case has a height of 100%. So the parent has a firm size is as I am this, I'm not min this or max this, that HTML says I am 100% and the body height can resolve 100% of itself correctly, because now it's not it has something to resolve against that has a firm size. So anyway, hopefully that clears up why your body height 100% doesn't doesn't stretch to the space and is always collapsed. And now you can just live live free just set that height 100% on HTML and I think it'll solve most of your issues. Yes, and a great explanation for this a way that I think about it sometimes too is like when you don't have any content also in the body, it's not going to be as tall as the space that you might be viewing it in the viewport. So having that content is really something that determines the height of any element intrinsically, any something to grab onto. So another solution for this is actually using viewport based units instead of percentages. And viewport units are a way to have a more concrete value that looks at the viewport size. So you can use like VW for viewport width or VH for viewport height, and you could set something to viewport size units instead of percentage size units. So that's one way to deal with it. So if you do like 100 VH for the height, similarly to percentage, you might get some overflow because it might be even taller than you expect. So there's actually new viewport units called dynamic viewport units, where there are a few there's SVH and SVW which is a small viewport height and small viewport width. And there's also LVH and LVW which is a large viewport within viewport height. And then there's dynamic viewport within viewport height, which is DVH and DVW. And these dynamically adjust based on if you have like a header that pops in on mobile. And that's where you run into additional viewport sizing issues and 100% sizing issues and overflow is when you're on different device types. So I like to use DVH now for any kind of demos I use where I wanted to stretch and be 100% of the viewport height and the dynamic viewport height. So that's what I would recommend for any type of full sizing. If you don't have content, for example, that fills all that space, like, and you still want to have like an action bar on the bottom, like a header on top and have something nestled in the middle. DVH has saved me so many times. So another thing is if you also want to make sure that it's stretching and your element is absolutely positioned or fixed positioned, you can use VH or VW with your viewport based sizing instead of percentages, or you could use the new dynamic units to here. These units are relative to the viewport, so they'll work even if the element is not positioned normal in the flow of the document in the normal flow of the document. And that's something that you might run into also is if you have these absolutely your fixed positioned elements. And then you're trying to position them with percentages, like oftentimes it collapses its position, essentially, it goes into a different flow. And you might be expecting to look at its its Dom parent, and that's not the actual size that that element is going to look at. So another case for viewport based units in your style sheets, I use viewport units a lot. Yeah, that brings up a good point, too, that like viewport units don't take account the scroll bar and stuff. And so they're either like easier to put in your style sheet, but they can overshoot or undershoot in the value. And that's a reason I stick with percentages. Also DVH just came out. So if you need to do something that's retro anyway, we have a lot of ways to fill the viewport now. Yes, but it is newer, but it has been supported since November of last year, November 2022 in Chrome. Let's see here, Safari, March 2023. So that was earlier this year. And then in, oh, it's not supported in Firefox, never mind. Never mind. Don't use this in real life use viewport units. I thought this was cross browser, but oh, see me like use VH don't use DVH. Oh, wait, wait, I was looking at the wrong thing. I was looking at DVH static method in a function. Which is interesting that pops up first in, can I use? DVH has been supported since March 2022 in Safari, November 2022 in Chrome, and May 2022 in Firefox. Okay, that's what I thought. These have all been out in every single modern browser for over a year now. So they're safe to use. Nice. Cool. Excellent. Yes, if like, if I'm doing overlays, like a dialogue or something like that, I'm not going to reach for percentages. I'm going to use DVH for sure. Okay, well, another reason your percentage might not be resolving to what you want is for like a child element is because the element is positioned to absolutely are fixed just like we're talking. Absolutely in fixed position elements are removed from the normal flow of the document, just like you were saying again, and they're not affected by the height of their parent elements. You might need to give the parent element a height or a width may even be able to set it to 100% of its, if its parent has a size. So this is again, we're like, where is this in the page? If it's a fixed element, it's now attached to the sort of HTML and your percentages are going to be resolving against whatever size that is. So be aware. Yeah. So also a weird thing that you might not realize is when you have the element in a flex or a grid layout, Flexbox and grid layout actually use their own rules for determining the size of elements. So percentages might not work as expected. And you can see that if you have something in flex and stretching. So percentages can be really challenging with intrinsic design when you're working with elements exactly in a grid or some other format. And it doesn't really work in that context. So if the child is in a flex or a grid, it might not have a defined height. And that's why you can't really query the block size of a grid item for a container query style either, which is a challenge for container queries, because you might have something in a grid and you want to query the block size, but it might not have an intrinsic size because it's filling its grid parent space. That's a challenge. It also might be a challenge with percentages. Yep, stretch, no stretch, align, don't align, you know, all those different things are impacting what the size of this thing is resolving to and grid wants to control that a lot, right? So the percentage, it's going to struggle in that scenario. All right, so we talked about percentages earlier about how they kind of resolve differently. We got width, height, margin, padding, font size. Let's kind of recap some of those, because I think this is just a good healthy reminder for folks. So like padding top, if I put padding top 20%, this resolves to 20% of the width of its parent, not the height. Which is funny, because you might be thinking of padding mentally like the space above and below if you're doing a padding top specifically. So there's also a very different definition of percent for font size. So if you use font size, you can set it to like font size 120%, which I do for headers sometimes. That's a completely different measure that's relative to the nearest inherited font size. So that would depend on the closest font size in the chain to the element that you're styling. So nothing to do with width or height. It's looking for the nearest defined font size. So funny. And then, yeah, the specialty one for transform translate, it's against itself. This is why like translate X negative 100% moves the element perfectly out of its own containing block, which is, love that one. Another funny one, like thinking about containers as background size, because if you have background size and you have a percentage, actually this is similar to like a gradient too when you have percentages there, it's relevant to the background position area of that element. So there you kind of get this like difference where it's not looking at a percentage with their height with background size like the location. And same thing with linear gradient or radial gradient or anything. If you're using percentages there, it's looking at the width. But then if you change the size, you can get like a squished gradient too. So you should be careful if you're using percentages and gradients, because it might be a different view than you expect if the size changes. I mean, it's why we have so many units in CSS, like sometimes percentage is exactly what you needed. And sometimes it's totally going to be weird and not right. That's why we have so many. There are so many different ways to use percentages. And it makes sense because there's different needs, like font size is very different need than a transform or translate than a width or a padding or a margin. But yeah, the percentages can be great, they can also be tricky. And another place a percentage doesn't work is SVGs. So if you're trying to do SVGs, they're responsive by default. If you set the whole width of it to 100%, then you size it up or down. But you have to do unit list dimensions for the actual path data. So if you're trying to like think about writing the stuff by hand or how it relates to other parts of the SVG, focus on SVG within the viewport dimensions of your SVG, the view box with SVG. And then you could size it up or down with percentage SVG. Yep, well said. And the last thing I want to cover here is cyclical percentage issues. So this is in the spec. And it's pretty easy to imagine, especially when you're doing intrinsic design, but like sometimes the height of a box depends on its children. And those children might be using percentages that reference the parent. Can you smell the issue that's happening here? Ooh, yeah, that doesn't smell good. Imagine a parent. Imagine a parent wants to contain the entirety of a child and then the child wants to be 50% of the parent. And you're like, this is like Spider-Man where they're all pointing at each other, like you tell me the height. It's like, no, you tell me the height. No, you tell me the height. Well, good news is the spec has instructions on how to resolve these intrinsic percentage issues. And since percentages have to resolve against different things, depending on which property they can be used with, there's numerous scenarios. I am not going to cover them here, but you can check the show notes for a link. If you're interested in the nitty gritty details about cyclical percentage resolution, they break down the scenarios pretty good and explains why they resolve the way they resolve. So anyway, I just wanted to mention cyclical percentage resolution. That's a good one to end on. I feel like that's something that people don't always think about until they run into it. And then it's like, oh, I've used percentages in one too many places now to figure out how to correct the references here. Yeah. So thank you, Adam. And also thank you, all of us, all of us, all of you for joining us today. I think it's always fun to talk about something that's so common. And yet we just have so many potential pitfalls with this topic. So I'm glad that we covered percentages and thank you for joining us in today's episode. Yeah. If you have any CSS questions, we'd love to answer them on the show. Just tweet us with the hashtag CSS podcast. I'm Yuna. That's at UNA. I'm Argyle, ARG, YLE, INK. Your question could help a lot of people. And just as a final note, if you did like the show and our conversation on percentages or even us just going through common CSS issues, please give us a review on whatever podcast app you're using right now to listen to the show or if you're watching it on YouTube, leave us a comment or share this podcast with a friend because that's how other people discover our show. And that means that we get to spend more time on making sure that we have cool little demos and also just topics that people care about and make sure that we spend time focusing on that for you. Yeah, we had a question recently that I still don't know the answer to. I'm trying to figure it out. That means it was a good question. Thank you for sending that in. It's been vexing me for days. You will get a response, I swear. Anyway, thanks, y'all. We look forward to your questions. And we'll see you all next time. Bye.