If you've ever wrestled with animating a collapsible accordion, a sidebar, or a gallery that expands on hover, you know the drill. CSS transitions on height or width sound simple. Until they demand setting fixed dimensions. Suddenly, your dream turns into a nightmare of overflows, janky reflows, and endless JS hacks. But what if you could animate size changes without ever touching explicit sizes? What if the content itself dictated the flow, and the browser handled the smooth interpolation?
Enter CSS Grid's secret sauce: animating grid-template-columns (or columns) with fractional units like 1fr and 0fr. This technique lets you toggle between collapsed (0fr) and expanded (1fr) states, where the animation glides effortlessly based on the actual content height or width. No guesses, no hacks. It's responsive by nature, performant and keeps your markup clean and semantic. In short, it's the elegant fix for one of CSS's oldest headaches, perfect for modern UIs that feel alive.
The Problem: Why Traditional Size Animations Suck
Picture this: You're building a FAQ accordion. Users click a question, and the answer should slide open gracefully. Easy, right? Slap on transition: height 0.3s ease; and toggle from height: 0 to... what? height: auto? Nope, you can only animate intrinsic properties which rules out auto. height: 200px? Sure, but now resize the browser. Boom, content clips on mobile. Or worse, the text wraps differently, and your "perfect" height is a lie.
Hardcoded Dimensions Break Responsiveness: Fixed pixels ignore font sizes, viewport changes, or dynamic content.
Performance Hits: Animating height triggers layout recalculations (reflows), which can stutter on complex pages.
Maintenance Mayhem: Every content update means tweaking CSS. And accessibility? Screen readers hate arbitrary sizes.
Enter Grid. By wrapping your content in a grid container and transitioning the track sizes, you let the browser compute the "end" state dynamically. 0fr collapses to zero without a trace, while 1fr expands to fit the content exactly. Add overflow: hidden on a wrapper div, and you're golden.
The Magic: How It Works Under the Hood
At its core, this leverages CSS Grid's ability to define flexible tracks that respond to content. Here's the blueprint:
Grid Container Setup: Your animating element becomes a display: grid with
grid-template-rows: (x)fr which gets toggled between 0fr and 1fr.Transition the Template: Apply animations to the container. Browsers smoothly interpolate fractional units—0fr to 1fr feels natural.
Content Wrapper: Nest your actual content in a child div with overflow: hidden. This clips the reveal during animation, preventing peek-a-boo effects.
Don't put sizing properties like padding or margin on the container. This will cause all sorts of animation jank. Instead, put those properties on a child in the container.
Trigger It: Use CSS classes, checkboxes, or a sprinkle of JS to flip the variable.
Bonus tricks: Because it uses grid, alignment properties are in play. You can use things like align-self/justify-self to position elements when they are transitioned in/out.
Now we know the why. Let's look at the how:
Animating Height
To animate height, use the grid-template-rows property:
Animating Width
To animate width, use the grid-template-columns property:
Animating both height and width
You can even animate both width and height, using both the grid-template-columns and grid-template-rows properties together:
Final Thoughts
Don't forget, you can always animate each transition separately, creating interesting animations.
So there you have it. CSS Grid's fractional transitions unlock a world of fluid, frustration-free size animations that adapt like they were born for it. We've covered the pitfalls, the fixed dimensions-less magic, and hands-on code to get you shipping polished interactions today. The beauty? This isn't just a trick. It's a mindset shift toward layouts that evolve with your content, boosting performance and user delight across the board.
