DEV Community

Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at blog.logrocket.com on

New in Firefox 66: animating CSS Grid

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:

.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):

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:

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

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.

.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):

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.

.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:

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:

Conclusion

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

https://logrocket.com/signup/

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.


The post New in Firefox 66: animating CSS Grid appeared first on LogRocket Blog.

Top comments (0)