Facundo Corradini Front-end developer, CSS specialist, best cebador de mates ever.

New in Firefox 66: animating CSS Grid

4 min read 1200

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.

Animating grid rows and columns

Since Firefox 66, the properties controlling the dimensions of Grid tracks are now animatable. That means grid-template-rowsand 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:

   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)

{ box-sizing: border-box; } body { background-color: #23262d; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr; max-width: 400px; height: 400px; gap: 20px; margin: 80px auto; animation: resize 3000ms ease infinite both; } .item { –color2: 36; –color2: 76; –delay: 0ms; background-color: hsl(var(–color1), 100%, 60%); animation:

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>
  display: grid;
  animation: push 2s linear infinite alternate;
  grid-row: 2;
@keyframes push{
    grid-template-rows: 0fr auto;
    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)

run in FireFox Nightly to see animtion html { –rect: 200px; –red: #F23337; –blue: #317CFF; –green: #64F82A; } .grid { animation: slideAround 10s infinite alternate linear; background: #111; display: grid; height: 100vh; overflow: hidden; will-change: grid-template-columns, grid-template-rows; } .rect { animation: colorShift 10s 250ms infinite both linear; background: black; height:

I’ve created a pure CSS infinite Pong demo using the same technique:

CSS Grid infinite pong (Firefox Only)

grid{ width: 100%; height: 100%; display: grid; grid-template-columns: 20px 0fr 20px 1fr 20px; animation: pong-h 2s linear infinite alternate, pong-v 1.4s linear infinite alternate; will-change: grid-template-columns, grid-template-rows; /*quick and dirty hack to fix the bounds */ background-image: linear-gradient(transparent 40px, darkgrey 40px, darkgrey calc(100% – 90px), transparent 0); padding-top: 50px; }

Gaps can also be animated

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-gapand grid-row-gap properties can also be animated by defining a simple @keyframesrule. 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

  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 300px;
  animation: gap 2s;
@keyframes gap{
    grid-gap: 100%;
    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)

sides { animation: 0.7s curtain cubic-bezier(.86,0,.07,1) 0.4s both; display: grid; grid-template-columns: 50vw 50vw; } @keyframes curtain { 0% { grid-gap: 100vw; } 100% { grid-gap: 0; } } html, body { height: 100%; margin: 0; font-family: “Arial Black”, sans-serif; } .intro { height: 100%; overflow: hidden; display: flex; justify-content: center;

A note on performance

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.

The full pixel pipeline

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-changeshould 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;.

How about other browsers?

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.

  display: grid;
  grid-template-columns: auto 1fr;
  width: 0;
  animation: grow 3s ease-in-out infinite alternate;
@keyframes grow{
    width: 200px;

Here’s a basic example based on the code above:

Animating CSS Grid in Chrome

container{ widht: 100%; height: 100%; display: grid; grid-template-columns: auto 1fr; } .growing{ background-color: red; width: 0; animation: grow 3s ease-in-out infinite alternate; } @keyframes grow{ to{ width: 200px; } } .shrinking{ background-color: blue; } html, body{ height: 100%; } 🕑 One or more of the npm packages you are using needs to be built.

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)

Transitions on grid-template-columns (sort of..) CSS Grid is supposed to have five animatable properties: grid-gap, grid-row-gap, grid-column-gap, grid-template-columns and grid-template-rows But browsers have not implemented it so far. Here’s a typical example where we would like to animate the grid-template-columns : adjusting the column track width for the aside menu.


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.

Plug: LogRocket, a DVR for web apps


LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

Try it for free.

Facundo Corradini Front-end developer, CSS specialist, best cebador de mates ever.

Leave a Reply