#277: Animating Height

[Robin]: 🤔 Is it :before or ::before? I always get a little confused when writing a pseudo-element like this…

.element:before { }
.element::before { }

Spoilers: it’s ::before. Sorry to start this newsletter off with so much drama. I should have better prepared you for this hot take in advance.

[Chris]: We covered this a few years back as well. The only reason you’d use the single-colon syntax is if you’re needing to support IE 8. The deepest people tend to go these days is IE 11, but it’s more common not to support IE at all. So yeah, double colon for sure.


Have you ever heard about the Properties and Values API? I hadn’t! Ruth John wrote all about it a while back and the gist is that instead of grabbing the CSS of an element like this:

const elementWidth = getComputedStyle(myElement).width;
// returns '300px'

Where you’re just getting that 300px as a string and causing a layout shift, now we can do something like this…

const elementWidth = myElement.computedStyleMap().get('width');
// returns CSSUnitValue {value: 300, type: 'px'}

elementWidth.value // 300
elementWidth.unit // 'px'

…so we can now grab the value and the unit independently and update them much easier now. Also, we don’t get a layout shift! Neato.

That’s the Typed Object Model at work and it can be incredibly handy.

[Chris]: I just noticed in the Motion One docs the other day (and I write about it lower down in this newsletter as well), that this API has the ability to make libraries much smaller :

As support for the CSS Properties and Values API improves, Motion One will be able to drop even more weight to get down as low as 1.8kb.


I thoroughly enjoyed this post from Yuan Chuan where they made this fancy border pattern with handwritten SVG

I have to admit that the underlying code of an SVG often scares me a little bit and I rarely, rarely end up editing the SVG code itself (besides maybe changing a few attributes like the fill or stroke here and there). I guess that’s a shortcoming I need to get over because to think about SVG as a write-only format like a JPG or something (a file format that you export but don’t ever edit by hand) is probably the wrong way to think about it all. And all the possibilities that open up once you understand the innards of an SVG the way that Chuan does here! It’s just so neat.

Oh, and make sure to check out the rest of Chuan’s blog posts because there’s so much other great stuff going on here, too.


Last week, Ana Tudor explored how to recreate this icon glassmorphism effect in CSS:

If the designer on my team gave me this thing to work on then I would growl and hiss at them until they changed everything about it. But Ana? She’ll gladly take the challenge to do something difficult and annoying with CSS. And so you can see in this post, where Ana tries a bunch of different ways to create this lovely glassmorphic effect (which I didn’t know was a thing until I read this post by Catherine Rasgaitas).

Anyway, of my favorite things about Ana’s writing is that she ends up digging through the spec to see if something in the browser is an intentional design decision or a bug. And if you’ve ever gotten to that point I think it’s perhaps the most bewildering part of being a web developer.

On a lighter note, it’s extremely fun watching Ana make a ton of cool demos this month, like this one:


Dang, cleanup.pictures is not only a great domain but also a fabulous tool. It lets you highlight something in the picture and remove it like you can in Photoshop.

I’d say that this is in a similar category as remove.bg or the marvelous lalal.ai which lets you remove the background of an image or isolate certain parts of a song (like taking the acoustic guitar out of a song with bass and drums and vocals in it).

There’s already a Figma plugin for remove.bg which lets you do all of this right inside your designs without having to go to the website itself.


Abram Thau made a great walkthrough about how to create a dark mode with multiple color themes in React.

Using React Scoped CSS is my favorite way to keep each component’s CSS encapsulated to prevent name collision messiness and unintended style inheritance. My previous go-to for this was CSS Modules, but that has the downside of making the in-browser DOM look like a robot wrote all of the class names… because that’s exactly the case. This lack of human-readability makes debugging far more annoying than it has to be. Enter React Scoped CSS. We get to keep writing CSS (or Sass) exactly the way we have been, and the output looks like a human wrote it.

React Scoped CSS sure looks neat. One of the problems you often get with CSS Modules is that in production you can’t debug stuff. So your HTML tends to look like this:

.styles__red__eegJCA {
  background: #309dcf;

With React Scoped CSS it creates CSS like this instead:

.title[data-v-15763057] {
  background: #309dcf;

p[data-v-15763057] {
  color: #fff;

That way you can still read the class names and the markup somewhat easily. Neat!


I sure liked this post about improving Cumulative Layout Shift at Buzzfeed, mostly because they’re so honest about the scale of the problems they tackled:

[…] our Real User Monitoring (RUM) data showed only ~50% of users were getting a “good” experience.

Oof. The trick was really getting good data because at first the team found it hard to see the performance problems users were experiencing. But after a great deal of faffery, the team at Buzzfeed figured out a way to show their team what the biggest problems were, like this:

That’s a chart showing the worst element on the page by how many users are seeing it and the crappiness of the CLS score. It’s a neat way to quickly get a glance of which elements suck the most and those that need to be tidied up. Besides the tool, I really liked the process that the team outlines this post and I’m particularly excited for them to document more of these sorts of findings. Performance is hard!


Expanding/collapsing elements with CSS is a real pain. Brandon Smith wrote about this complex conundrum a while back:

We’ve all been there. You’ve got an element you want to be able to collapse and expand smoothly using CSS transitions, but its expanded size needs to be content-dependent. You’ve set transition: height 0.2s ease-out. You’ve created a collapsed CSS class that applies height: 0. You try it out, and… the height doesn’t transition. It snaps between the two sizes as if transition had never been set. After some fiddling, you figure out that this problem only happens when the height starts out or ends up as auto. Percentages, pixel values, any absolute units work as expected. But all of those require hard coding a specific height beforehand, rather than allowing it to naturally result from the size of the element content.

This is all pretty annoying and has been for a good long while. This is ideally what we want to see…

You click an element and content appears, pushing the content down below. The difficulty here is that the hidden box can change height depending on the content within it so in the past most folks have made this toggling/appear act work with JavaScript. But shouldn’t we be able to do this with CSS?

That’s the conclusion that Nelson Menezes came to when he figured out a new way to animate height: auto with CSS Grid. It works a little like this:

.expander {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 1s;

.expander.expanded {
  grid-template-rows: 1fr;

Which… is pretty dang smart! Although sadly this only works in Firefox today, but if we all star the heck out of this Chromium bug then perhaps we can this to work in Chrome, too.

What’s new at Netlify

October was a heckuva busy month over at Netlify! First, there was Jamstack Conf which had its largest ever turnout. Then the team went into turbo mode and shipped all kinds of goodies that make their service even better, like faster, more reliable page loads with an update to On-demand Builders, a new integration that can record Loom videos right from a Deploy Preview and save as a comment to a Git pull or merge request, new experimental support for Rust in Netlify Functions, an update to Netlify Analytics, and much, much more. It’s awesome to see this much momentum!


Are videos impacting your page’s load time? Now, Deliver optimized videos in the right format, quality and size based on the user’s device in real-time. Delivering stunning visual experiences just got simpler, Try ImageKit’s forever-free plan today!

[Chris]: I’ve seen a couple of new animation frameworks in the last couple of weeks:

  • Theatre.js: “is a JavaScript animation library with a GUI. It animates the DOM, WebGL, and any other JavaScript variable.”
  • Motion One: “A new animation library, built on the Web Animations API for the smallest filesize and the fastest performance.”

I’m not such a heavy user of animation and animation frameworks that I feel like I can evaluate them fairly at a detailed level.

There is certainly some interesting stuff going on though! Theatre.js providing a full-blown interface for building out animations is pretty cool. Notably, I’ve seen a number of projects that have tried to do this ultimately fail. GUIs for animation are no joke to pull off, so hats off for shipping here.

Motion One’s focus seems to be providing a cleaner API on top of the web’s native Web Animation API (WAAPI). Which then, as you might expect, leads to a fairly small size since it doesn’t have to recreate the core animation engine. The docs spend time talking about how comparatively performant it is, with a small irony being that it’s shipping client-side JavaScript on top of WAAPI so if performance and bundle size are the top concerns… use WAAPI alone?

(Motion One is from Matt Perry. We did a video with Matt on Framer Motion, which was/is pretty cool. Matt certainly has some animation framework pedigree.)

This all makes me think about a couple of things. One, this feels like a new cohort of animation libraries, of which there have been many. I feel like I’ve seen an awful lot of animation libraries come and go. Greensock is the one that has stuck around for the long haul and continues to innovate. I’d bet my bottom dollar that it’s because they have a proper business model around it, as as much as people like to whine about the licensing stuff around that, it’s made them the predominant library in the space.

So that makes me think about the longevity stuff. Do you make choices based on a desire for technical longevity? Not absolutely everything built on the web needs to, but I think more things should think about that. And it’s a twofold game:

  1. Is the technology itself going to last?
  2. Is your knowledge of using that technology going to last?

In other words, if I’m going to invest in learning new technology, I want to have a reasonably strong hunch that this technology is going to be around for quite a while, and that what I need to learn to use it is going to be useful knowledge to have for longer than a one-off. I’d like to cultivate that knowledge over time, not lose it to some other ephemeral tech.