#249: Decoding async, tree rings, and flexbox gap

[Robin]: I thought I knew everything when it comes to responsive images, but this article by Addy Osmani sure proved me wrong. He writes about how images impact performance and how that ties into Google’s Core Web Vitals but goes step by step, from a humble img tag, all the way and up to the pretty complex HTML that he ends the article with.

One good reminder from Addy is that for hero images we can often save a bit of time if we preload our images in the <head>, like this:

  <link rel="preload" as="image" href="donut.jpg">

But you can also defer the decoding of this image, which I had no idea was even a thing browsers could do:

Browsers need to decode the images they download in order to turn them into pixels on your screen. However, how browsers handle deferring images can vary. At the time of writing, Chrome and Safari present images and text together – synchronously – if possible. This looks correct visually, but images have to be decoded, which can mean text isn’t shown until this work is done. The decoding attribute on <img> allows you to signal a preference between synchronous and asynchronous image decoding.

So! What does this mean? Well, you can write something like this…

<img src="donut.jpg" loading="lazy" decoding="async">

…which gives the browser permission to show content before the image has finished the loading and decoding process. That’s a pretty neat trick, if you ask me.

From JavaScript to paper: a linocut adventure

I absolutely adore blog posts like this one from Monica Dinculescu where she programmatically created tree rings with JavaScript.

One of my favourite kinds of art to make involves taking nature and seeing it as simple shapes. Buildings are cubes, flowers are circles, hills are curves. Shells are spirals. Tree rings are weird circle bois, and they are some of the best. I’ve wanted to make a generative art of a tree ring for a long time, but everything I made kept sucking (scroll to the bottom if you don’t believe me. Shit was bad bad). I finally made something I like, I thought it might be neat to write a little bit about The Process™️, since it involves both JavaScript and murderous little knives.

Monica then takes those tree rings she created with JavaScript and creates linocut prints with them. Also, she links to another great post called Noise in Creative Coding by Varun Vachhar which talks about how to programmatically create noise in all sorts of different ways. There’s all sorts of rabbit holes to fall into here when it comes to complex particle systems and what not. But my favorite thing about Varun’s essay is that he doesn’t just write about how to create noise by showing us code, he also creates tons of visualizations that you can manipulate:

This reminds me, the other day I came across another great blog post in a format like this where Bartosz Ciechanowski uses these fantastic 3D illustrations to explain how the internal combustion engine works:

Bringing in these 3D examples to explain complex topics is such a great way to really move the pieces around in your mind and play with them. One thought I had whilst reading this essay was this: is it possible to make a 3D rendered internal combustion engine with CSS alone? Who knows…

Anyways, these essays with nifty interactive diagrams seem to be having a bit of a renaissance lately as all this great work reminds me of Bret Victor’s essays. A few years ago he made an interactive essay on the ladder of abstraction that lets you move the essay around as you read it:

Safari 14.1 Adds Support for Flexbox Gaps

Back to important front-end news: this is pretty big. The latest version of Safari now supports gap whenever you use display: flex like this:

.container {
  display: flex;
  gap: 1.5rem;

Now each of those items will be spaced apart correctly, just as they are in CSS Grid.

Why’s this so handy? Well, lately I’ve noticed how a lot of folks will use display: grid instead of flex simply because they get to use gap out of the box. With flexbox, up until now, you’d have to set margins or padding on child elements and sometimes that can be sort of annoying and cause layout issues. So hurray for this update to Safari!

Your Team is Not “Them”

Sarah Drasner wrote about how we talk about our team which is especially useful if you’re an engineering manager but I still found it particularly interesting as a humble ol’ web designer:

Let’s talk for a moment about how we talk about our teams. This might not seem like something that needs a whole article dedicated to it, but it’s actually quite crucial. The way that we refer to our teams sends signals: to stakeholders, to your peers, to the team itself, and even to ourselves. In addressing how we speak about our teams, we’ll also talk about accountability.

How should we talk about our team then? Sarah continues:

Your team is “we”. You are a driving force of that team, no matter how high up the hierarchy chain. What happens on that team is your responsibility. When you speak about your org, you should include yourself in the statement.

I loved this note and I think what I’ve taken away from this piece by Sarah is to always be honest. It’s easy to let your ego get in the way and blame others for your own mistakes but standing up and saying “wow, I really effed that up” is a sign of character. If you continue like that smart and kind people will go out of their way to work with you. And that’s ultimately good for your career.

[My lawyers would like me to say that I am absolutely not subtweeting anyone here, thank you for your time.]

Web Languages as Compile Targets

Chris compares the importance of learning HTML with music:

Seriously though, I’m not exactly sure when the perfect time to learn HTML is. Early on, for sure, but I wouldn’t blame anyone for not learning it first. I’m sure I learned it in the context of WordPress PHP templates. I’m sure a lot of people are learning it in the form of JSX or .vue files these days. That’s fine. It’s like learning to play “(Sittin’ On) The Dock of Bay” on guitar before you learn about keys and scales and voicings. But if you never circle back to the fundamentals, it’s limiting, and in the case of the web, damaging.

Chris is riffing off a blog post from Jim Nielsen here when he argues that people are treating HTML as a compile target, as in something you don’t need to write as an author, but rather a language that only a browser needs to read.

That causes a bunch of problems though:

HTML often gets written as part of a transaction: write something, anything, and see a result. Use it to group words, hook into styles and interactions, or construct specific pieces of UI. This has almost nothing to do with communicating meaning and structure.

HTML often becomes scaffolding for building UI (for which few elements are needed) when it was designed to be markup for outlining the meaning and interactivity of content (for which many elements are needed).

If we don’t learn the basics, as Chris described as the fundamentals, then we limit what we can do with the web but we also make worse experiences for it. Keeping up to date on the very basics will also mean fewer dependencies and fewer bytes of useless code that gets sent over the wire.

A Complete Guide to Custom Properties

When it comes to learning about the fundamentals, the same can be said for CSS. So learning about custom properties is a great idea because it’s an example of a new-ish addition to CSS that unlocks so many design opportunities for us.

Reading this guide to custom properties also reminded me that they can be used for more than just defining color variables. It’s important to remember you can define file names with it, like in this example below where Chris switches out background images when the viewport changes size:

body {
  --bg1: url(./img/angles-top-left.svg);
  --bg2: url(./img/angles-top-right.svg);
  --bg3: url(./img/angles-bottom-right.svg);
  --bg4: url(./img/angles-bottom-left.svg);
  --bg5: url(./img/bonus-background.svg);
  background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);
@media (min-width: 1500px) {
  body {
    background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);

What this has me thinking is this: I reckon there’s some mighty interesting things you can do with background images and container queries, once they land of course. And we’ll be sure to keep you updated when they do.

Fun with the CSS path() function

In this post, Jhey Tompkins reminds us all that clip-path: path() can make for some pretty interesting shapes with CSS alone:

On that previous note about CSS custom properties, Jhey sets the path into variables that can be reused again and again but also for legibility purposes, too:

.portrait {
  clip-path: path(var(--clip, var(--splat)));
.portrait:hover {
  --clip: var(--splattier);
.portrait:active {
  --clip: var(--splatted);

Usually I’d automatically reach for SVG to create these sorts of shapes and so it’s pretty amazing to think that this is now possible with nothing more than some fancy CSS trickery.

axe DevTools

Is your website accessible? Deque’s axe DevTools Pro makes accessibility testing easy for dev teams. Find and fix potentially critical issues while you code. No expertise required. Build more accessible experiences and get started for free today.


We’re excited to announce first-class support for Core Web Vitals in Raygun. Now you can get a detailed overview of how your website performs against Google’s modern user-centric metrics, alongside all the diagnostics you need to take action.

[Chris]: I think I’m part of the problem here.

Well, to be sure, I’m part of lots of problems. But to pick one, in particular, I’m thinking about is the profession of UX. I’d like to think I’m huge on UX. User experience, right? That’s, like, all that matters when building websites. The literal one single thing we’re all dead focused on.

There is an actual career path for UX. UX is a job title. You can literally hire UX people. And that’s where me being a problem comes in: I don’t really know what a dedicated UX person does, or when/how to hire them. I know that it doesn’t mean “wireframe people”, because that’s either laughed at as something outsiders think UX people do, or more seriously presented as well, that might be part of a process, but the work is more holistic than that. That is somewhat helpful, as I can imagine one doesn’t jump into wireframing without understanding what the wireframes are supposed to help someone do. Does that mean user testing is part of it? Or even broader: product strategy?

Peter Merholz talked about some of the trouble within the UX sphere itself in Waking up from the dream of UX:

What’s happened by 2021 is that UX is not interesting in and of itself anymore. UX is a given. As Joe Lamantia said in a mailing list I’m on, “it’s furniture.” And the challenges and frustrations people are expressing are largely due to this maturation.

We’re moving from “the dream of UX” to “the reality of UX.”

Maybe Peter is reflecting on changes to the UX profession thrust upon it by people like me who don’t know what to do with it. Furniture does seem like a good way of putting it. I expect everyone on the team to be thinking about users literally all the time, and yet don’t have a single employee dedicated to it solely.

This callout about power resonates with me:

If I have a front-end developer on my team, they are of course fully capable (and expected) to be thinking about and talking to users as well. And if they see an opportunity for a UX improvement, through their skill set, they are empowered to do something about it directly. Same with a visual designer… they can bake UX improvements into the high-fidelity mockups that guide what we build. To me, it seems like the power dynamic is that you can do more about UX if your “actual job” is “something else”. I can see how that is unfair and potentially dangerous though, as someone who is wholly focused on UX might be literally better at it than someone who is trying to balance that work with building React components or leading design requirements meetings.

Anyway, kids are are clearly a little disenchanted with the job, and it’s probably my fault.