{"id":378862,"date":"2024-06-28T06:44:01","date_gmt":"2024-06-28T13:44:01","guid":{"rendered":"https:\/\/css-tricks.com\/?p=378862"},"modified":"2024-07-11T09:17:13","modified_gmt":"2024-07-11T16:17:13","slug":"transitioning-to-auto-height","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/transitioning-to-auto-height\/","title":{"rendered":"Transitioning to Auto Height"},"content":{"rendered":"\n

I know this is something Chris has wanted forever<\/em><\/a>, so it’s no surprise he’s already got a fantastic write-up<\/a> just a day after the news broke. In fact, I first learned about it from his post and was unable to dredge up any sort of announcement. So, I thought I’d jot some notes down because it feels like a significant development.<\/p>\n\n\n\n

The news: transitioning to auto<\/code> is now a thing!<\/strong> Well, it’s going to be a thing. Chrome Canary recently shipped support for it and that’s the only place you’ll find it for now. And even then, we just don’t know if the Chrome Canary implementation will find its way to the syntax when the feature becomes official.<\/p>\n\n\n

The problem<\/h3>\n\n\n

Here’s the situation. You have an element. You’ve marked it up, plopped in contents, and applied a bunch of styles to it. Do you know how tall it is? Of course not! Sure, we can ask JavaScript to evaluate the element for us, but as far as CSS is concerned, the element’s computed dimensions are unknown. <\/p>\n\n\n\n

That makes it difficult to, say, animate that element from height: 0<\/code> to height: whatever<\/code>. We need to know what “whatever” is and we can only do that by setting a fixed height on the element. That way, we have numbers to transition from zero height to that specific height.<\/p>\n\n\n\n

.panel {\n  height: 0;\n  transition: height 0.25s ease-in;\n\n  &.expanded {\n    height: 300px;\n  }\n}<\/code><\/pre>\n\n\n\n

But what happens if that element changes over time? Maybe the font changes, we add padding, more content is inserted… anything that changes the dimensions. We likely need to update that height: 300px<\/code> to whatever new fixed height works best. This is why we often see JavaScript used to toggle things that expand and contract in size, among other workarounds.<\/p>\n\n\n\n

I say this is about the height<\/code> property, but we’re also talking about the logical equivalent, block-size<\/code>, as well as width<\/code> and inline-size<\/code>. Or any direction for that matter!<\/p>\n\n\n

Transitioning to auto<\/code><\/h3>\n\n\n

That’s the goal, right? We tend to reach for height: auto<\/code> when the height dimension is unknown. From there, we let JavaScript calculate what that evaluates to and take things from there.<\/p>\n\n\n\n

The current Chrome implementation uses CSS calc-size()<\/code> to do the heavy lifting. It recognizes the auto<\/code> keyword and, true to its name, calculates that number. In other words, we can do this instead of the fixed-height approach:<\/p>\n\n\n\n

.panel {\n  height: 0;\n  transition: height 0.25s ease-in;\n\n  &.expanded {\n    height: calc-size(auto);\n  }\n}<\/code><\/pre>\n\n\n\n

That’s really it! Of course, calc-size()<\/code> is capable of more complex expressions but the fact that we can supply it with just a vague keyword about an element’s height is darn impressive. It’s what allows us to go from a fixed value to the element’s intrinsic size and back.<\/p>\n\n\n\n

I had to give it a try. I’m sure there are a ton of use cases here, but I went with a floating button in a calendar component that indicates a certain number of pending calendar invites. Click the button, and a panel expands above the calendar and reveals the invites. Click it again and the panel goes back to where it came from. JavaScript is handling the click interaction, triggering a class change that transitions the height in CSS.<\/p>\n\n\n\n