How to embed AV1 Image File Format (AVIF) images

New in Chromium 85 is support for the AV1 Image File Format (AVIF), which is pretty impressive:

AVIF offers significant file size reduction for images compared with JPEG or WebP; ~50% savings compared to JPEG, and ~20% savings compared to WebP.

🦊 Using Firefox and can’t wait to use AVIF images? Set the image.avif.enabled flag to true to enable experimental support for it.

Time to tweak the modern way to embedding images a bit, and add AVIF in there:

  <source srcset="/images/cereal-box.avif" type="image/avif" />
  <source srcset="/images/cereal-box.webp" type="image/webp" />
  <img src="/images/cereal-box.jpg" alt="Description of Photo" />

The browser will load the first source it can interpret, eventually falling back to the JPG if none are supported.

☝️ Now that Safari is about to support WebP in version 14, the image/jp2 image that was in the original snippet was also dropped.

How to Use AVIF: The New Next-Gen Image Compression Format →

UPDATE 2020.09.08: Jake Archibald just released an extensive post on AVIF packed with examples and comparisons, worth checking out.

The difference between aria-label and aria-labelledby

LΓ©onie Watson (@LeonieWatson) explains the difference between aria-label and aria-labelledby:

The aria-label and aria-labelledby attributes are both used to give an element it’s accessible name. The difference between aria-label and aria-labelledby is where they get that piece of text, and the clue is in the name. The aria-label attribute gives an element its label; an element with the aria-labelledby attribute is labelled by something else.

But don’t go adding of them everywhere, as you might not need ARIA (see The First Rule of ARIA) πŸ˜‰

The difference between aria-label and aria-labelledby

Serverless functions with Vercel

Have a static site but looking to add backendy stuff β€” such as subscribing to a newsletter β€” to it? Geoffrey Dhuyvetters from madewithlove walks us trough setting up a serverless function with Vercel (formerly known as Zeit):

In this article I’ll walk you through the steps to create serverless functions with Vercel. These functions will provide you with a place to add server side logic like verifying captcha’s, sending emails or liking posts that you can use in your static sites.

Serverless functions with Vercel →

What’s new / coming to Google Cloud Run?

At Google Cloud Next ’20, Cloud Run Product Manager Steren Giannini (@steren) walked us through some of the new things that are coming to Google Cloud Run.

Some highlights:

  • VPC Peering
  • Gradual Rollouts (with custom URLs per tagged release)
  • New Load-Balancing Features (Multi Region, Cloud CDN, IAP)
  • Easy Continuous Deployment
  • Min instances (no cold starts)
  • 4 cpus/4 GB RAM
  • 1 hour request timeouts
  • Graceful shutdowns (SIGTERM)
  • Server-Side Streaming
  • …

🧐 Unfamiliar with Google Cloud Run? Watch the video of a talk I recently gave on the subject.

Going Serverless with Google Cloud Run (

Back in June I was invited to speak at This year’s edition focused on DevSecOps and Security. My talk β€œGoing Serverless with Google Cloud Run” β€” which I have brought forward before at Full Stack Ghent and PHP-WVL β€” was a perfect match for it.

Cloud Run is a fully managed compute platform by Google that automatically scales stateless containers. By abstracting away all infrastructure management, us developers can focus on what matters most: building great applications.

In this talk I’ll show you not only how to deploy PHP/Node applications onto Cloud Run, but also how to create a build pipeline using either Google Cloud Build or Github Actions.

In mid August the video got released, which I’ve embedded below:

The slides are up on, and also embedded below:

Thanks to the organisers for having me, and thanks to the attendees for coming to see me. I hope you all had fun attending this talk. I know I had making it (and whilst bringing it forward) πŸ™‚

πŸ’β€β™‚οΈ If you are a conference or meetup organiser, don’t hesitate to contact me to come speak at your event.

Stealing Local Files using the Web Share API (in Safari)

One of the features of the Web Share API is that it allows you to share files along with your share intent:

if (navigator.canShare && navigator.canShare({ files: filesArray })) {
    files: filesArray,
    title: 'Vacation Pictures',
    text: 'Photos from September 27 to October 14.',
  .then(() => console.log('Share was successful.'))
  .catch((error) => console.log('Sharing failed', error));
} else {
  console.log(`Your system doesn't support sharing files.`);

As unearthed by there’s a big security issue with it in Safari/MobileSafari:

The problem is that file: scheme is allowed and when a website points to such URL unexpected behavior occurs. In case such a link is passed to the navigator.share function an actual file from the user file system is included in the shared message which leads to local file disclosure when a user is sharing it unknowingly. The problem is not very serious as user interaction is required, however it is quite easy to make the shared file invisible to the user. The closest comparison that comes to mind is clickjacking as we try to convince the unsuspecting user to perform some action.

In their tests they’ve successfully stolen the local /etc/passwd or even the entire MobileSafari history (which is nothing more than a .sqlite file).

Apple first stated that they are only going to fix it in the Spring 2021 (!) Security Update, but after the post went public it now looks that they’ve changed course, as by now a fix has been committed into the Webkit Source:

+static Optional<URL> shareableURLForShareData(ScriptExecutionContext& context, const ShareData& data)
+    if (data.url.isNull())
+        return WTF::nullopt;
+    auto url = context.completeURL(data.url);
+    if (!url.isValid())
+        return WTF::nullopt;
+    if (!url.protocolIsInHTTPFamily() && !url.protocolIsData())
+        return WTF::nullopt;
+    return url;
-    Optional<URL> url;
-    if (!data.url.isNull()) {
-        url = context.completeURL(data.url);
-        if (!url->isValid())
-            return false;
-    }
+    if (!data.url.isNull() && !shareableURLForShareData(context, data))
+        return false;

Bonus points for naming that class WTF πŸ˜…

Apart from that quick fix in the code, the issue is also being discussed at the spec level in order to prevent other implementers from making the same mistake.

πŸ€” What about Chrome you might ask? Google Chrome does currently not support the Web Share API yet. And if it did β€” and above that also were to allow file: attachments β€” it has an allowlist of permitted file extensions in place.

Stealing local files using Safari Web Share API →

Via Thomas Steiner (@tomayac) on Twitter

Semantically Identify a Heading Subtitle with ARIA role="doc-subtitle"

Over at CSS-Tricks, Chris takes a look at how to mark up a β€œDouble Heading”, a common pattern where you have a big heading with a little one preceding/succeeding it (as pictured above).

After going over a few options, the answer comes from a tweet by Steve Faulkner: use role="doc-subtitle" for the secondary heading. As per spec:

An explanatory or alternate title for the work, or a section or component within it.

   <h1>Chapter 2 The Battle</h1>
   <p role="doc-subtitle">Once more unto the breach</p>

Oh that’s nice! Support from JAWS/NVDA seems ok so it’s perfectly fine to use.

HTML for Subheadings and Headings →

Inception – Ten Years Later

Being a fan of Christoper Nolan’s work, I liked this look back at Inception β€” an amazing movie with a wonderful soundtrack β€” which recently turned 10.