Firefox is continuously improving, and the Mozilla team manages to surprise us with every new release.
We have seen outstanding improvements on their dev tools recently that are pushing many devs to use of Firefox in development, also the browser implementation of CSS modules and APIs are growing constantly.
One feature that has recently landed is the animation of CSS Grid. According to CSS Grid level 1 specification, some grid properties should be animatable, but no browser had implemented this aspect. All vendors chose to compromise and shipped Grid without it, so I thought this was a difficult (or impossible) feature to implement and I wasn’t expecting it to ever see the light of day. But luckily, I was wrong.
Since Firefox 66, the properties controlling the dimensions of Grid tracks are now animatable. That means grid-template-rows
and grid-template-columns
can be manipulated in animations with proper interpolation.
Implementation is really simple: as with any other CSS animation, just define the animation
for the element, and set a @keyframes
rule controlling it. For instance:
.element{ grid-template-columns: 1fr 1fr 1fr; animation: resize 2000ms ease infinite alternate; } @keyframes resize { to { grid-template-columns: 1fr 2fr 1fr; } }
Will provide a grid with three equal width columns (except if any of the grid-items have a bigger, intrinsic size… FR units are not so simple) animating back and forth to a grid with a wider central column.
There are some limitations though. Quoting from the spec:
Animatable: as a simple list of length, percentage, or calc, provided the only differences are the values of the length, percentage, or calc components in the list
This means the animation can only affect the sizing of the different tracks (not add/remove tracks from the template) and interpolation won’t work if mixing the unit types. For instance, a track cannot be animated from 40px to 1fr.
This example by Michelle Barker shows the basic works of a grid animation (with some color change for good measure):
grid-template-rows / grid-template-columns animation (Firefox only)
No Description
A nice trick to keep in mind is using empty tracks to push actual content around. We can position an element in a specific track (column/row) and have empty track animating in order to “push” the element around:
<div class="grid">
<div class="element"></div>
</div>
.grid{ display: grid; animation: push 2s linear infinite alternate; } .element{ grid-row: 2; } @keyframes push{ from{ grid-template-rows: 0fr auto; } to{ grid-template-rows: 1fr auto; } }
The code above will position the element in the second row, which will be pushed from the top to the bottom and back (as the first row will be growing from zero height to occupying all of the empty space).
One of my favourite examples of this technique is this awesome pen by Andrew Harvard, recreating the good ol’ bouncy DVD logo:
The DVD Logo (css grid animation)
A CSS grid animation experiment. Best viewed in Firefox Nightly. …
I’ve created a pure CSS infinite Pong demo using the same technique:
CSS Grid infinite pong (Firefox Only)
No Description
A feature that has been around for quite some time but stays unknown to most is the animation of grid-gaps. The grid-gap
, grid-column-gap
and grid-row-gap
properties can also be animated by defining a simple @keyframes
rule. This part of the spec even has almost-perfect browser support.
This opens the possibilities for other cool effects. For instance, we can separate actual elements, or make them start far apart and clash at the center.
The following code will make two grid-items start completely off-screen and collapse to the center
.grid{ display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 300px; animation: gap 2s; } @keyframes gap{ from{ grid-gap: 100%; } to{ grid-gap: 0%; } }
This pen by Manuel Matuzovic shows how it can be used in the “real world” (it’s animated on load, so refresh if you miss it):
CSS Grid Layout: Animating grid-gap (FF Only)
No Description
Even with the limitations, animating CSS grid properties can achieve awesome effects. There’s a caveat, though, as with any height/width changes, animating grid columns, rows, or gaps triggers changes in layout, which can be costly on performance.
Layout calculations are in the middle of the rendering pipeline, which means browsers will have to re-do layout and the following steps (paint and composite ) constantly during the animation.
It’s generally considered good practice to animate only the properties that change the composite step (which pretty much means opacity and transform only), so if you’re going to use CSS grid animations in production, do so purposely and responsibly. To minimise the impact on performance, animate only elements with few descendants, and with simple clipping/stacking context trees.
Also, consider using the will-change property to inform the browser which parts are gonna be animated, so they can optimise for it. Remember that multiple properties on will-change
should be chained as comma-separated values. So if you’re gonna animate both the columns and rows templates, use will-change: grid-template-columns, grid-template-rows;
.
Chromium browsers kind of animate CSS Grid, but without interpolation. This means we can define a @keyframes
animation that will be respected, but it will jump between the steps instead of transitioning smoothly. Think about how animating an element’s visibility
from hidden
to visible
makes a jumpy appearance while transitioning the opacity
makes it appear gradually.
Well, Chromium animates grid-like visibility, while Firefox animates it like opacity.
But hey! As always, with CSS, we can hack it. We might define the grid track (row or column) as some automatic size (auto
,min-content
,max-content
) then animate the width
/ height
of the grid-elements.
.container{ display: grid; grid-template-columns: auto 1fr; } .element{ width: 0; animation: grow 3s ease-in-out infinite alternate; } @keyframes grow{ to{ width: 200px; } }
Here’s a basic example based on the code above:
Animating CSS Grid in Chrome
A quick and dirty hack to animate CSS Grid tracks (columns / rows) with proper interpolation in Chromium-based browsers. The trick is defining the an…
Not super practical or performant, but it provides a sort of interpolated grid animation for some given use cases
A similar approach can be used for animations based on transitions instead of keyframes:
Grid-Template-Columns transition (hack)
CSS Grid is supposed to have animatable properties… but browsers have not implemented it yet. Here’s a workaround for one of the most typical use c…
The implementation of CSS Grid animation lets us add amazing effects to the interface. The impact on performance and the lack of support from other, more popular browsers probably means we’re not going to see this regularly yet, but the Firefox team has given us a great tool for developers and designers to experiment with, leading the way for great CSS effects and tools.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.