Bippity boppity browser interoppity

Issue #260.February 5, 2024.2 Minute read.
Bytes

Today’s issue: App Router regrets, a fully immersive Farmville experience, and using JavaScript to make the mazes on the back of the Fruity Pebbles box.

Welcome to #260.


Eyeballs logo

The Main Thing

A guy dancing hard with his cats

When the :has() selector just works

Bippity boppity browser interoppity

The Interop squad just posted their 2024 report about their progress last year, along with their goals for 2024 — and they’re still crushing it.

Quick review: The Interop Project was first organized in 2021 by Google, Apple, Microsoft, Firefox, and ui.dev to improve interoperability between browsers by encouraging browser engine teams to prioritize specific areas of focus. OK fine we didn’t help organize it, but this is our newsletter so we make the rules.

Every year, the Interop crew creates a set of of web-platform tests for each current focus area. From there, the individual browser teams work towards passing more and more of those tests, posting their updated scores to the Interop dashboard for transparency. Then they start over with new areas of focus and new tests for the next year.

At the start of 2023, only 48% of Interop tests were being passed by all three browser engines, but by the end of the year, they were at a 95% pass rate 🔥. That work is a huge reason why we can actually use platform features like Subgrid, :has(), and Container Queries.

Here are three interesting things they’ve got cooking for 2024:

  • The Popover API gives you a declarative, consistent mechanism for displaying content that always renders in the topmost-layer. It’s helpful for creating tooltips and notifications and was the #1 request in last year’s State of HTML survey.

  • Over 1,300 new accessibility tests are being adopted as a focus area, with the goal of fixing every a11y issue in every browser 🙏.

  • CSS Nesting lets you nest one style rule inside another, so you can write more concise and readable CSS. It’s already shipped in all major browsers, but Interop is working to ensure everyone aligns on one reliable syntax this year.

Bottom Line: Unlike most projects that got started during Covid times, it’s nice to see Interop continuing to thrive (RIP to all those sourdough starter kits).

        

Postman logo

Our Friends
(With Benefits)

Stanley from the Office dancing

When you convince your boss to send you to POST/CON

The biggest API conference is coming 👀

Postman’s POST/CON 24 is happening at San Francisco’s Union Square Hilton on April 30 - May 1, 2024, and it’s going to be massive.

Why is this the API event of the year? Postman not only knows how to throw a great party, but they also deliver insanely valuable trainings—so you’ll walk away with new, tangible skills you can immediately use at your job.

  • Day 1 features 8-hour, in-person workshops on collaborative API development, API prototyping, and more.

  • Day 2 includes talks and open labs from world-class experts like Gail Frederick (CTO of Heroku) and tons of incredible engineering leaders—all followed by a huge after-party.

Save yourself from FOMO and sign up for the conference that everyone is talking about.

Get 50% off your ticket by registering before Feb 13th.


Pop Quiz logo

Pop Quiz

Sponsored by Sentry

Their Director of Solutions Engineering is hosting a free Sentry tour to show you how to stop wasting cycles with the same bugs - so you can waste time on more fun stuff instead.

If you wanted to pause a CSS Keyframe animation using JavaScript, how would you do it?

<style>
  .circle {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-color: lightblue;
    margin: auto;
    animation: pulse 1s infinite ease-in-out;
  }

  @keyframes pulse {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(1);
    }
  }
</style>

<div class="circle"></div>
<button class="btn">Pause Animation</button>


Cool Bits logo

Cool Bits

  1. React Native is now available for the Apple Vision Pro. Now I can finally build the fully immersive Farmville experience I’ve been dreaming about since 2010.

  2. Maciej Kravchyk wrote about Adding type safety to object IDs in TypeScript.

  3. FusionAuth wrote a deep dive on How to use OAuth to add authentication To your React app. If you’re working on a React app and you have users (or you want to have them someday), you should probably check it out. [sponsored]

  4. Andy Jiang and Ryan Dahl wrote about what Deno was up to in 2023, including their focus on Node/npm compatibility, their performance work, and why they believe the Deno logo will always be cuter than than the Bun logo (jk).

  5. Brandon Bayer (founder of Flightcontrol) wrote about the good, the bad, and the ugly of his team’s recent Next.js App Router Migration.

  6. Mayank wrote about Some use cases for the revert-layer keyword.

  7. Labyrinthos.js is a procedural generator for crafting complex game landscapes like mazes, terrains, and biomes. Now I finally understand how they make the mazes on the back of the Fruity Pebbles box.

  8. CarbonQA built high-quality QA services for dev teams, so you never have to waste engineering time on QA testing ever again. Their US-based QA testers work directly in your tools and will help you catch bugs before something breaks. [sponsored]

  9. Julia Evans wrote about Dealing with diverged git branches.

  10. Million.js just released v3.0 of its optimizing compiler for React. “But wait, didn’t they already launch v3.0 back in December?” Yes, but apparently that was a soft launch — kind of like when I “soft launched” my new mullet on the first day of 10th grade, then went home and shaved it off when Stacy still didn’t notice me.


Pop Quiz logo

Pop Quiz: Answer

Sponsored by Sentry

You can use the element’s getAnimations method to get an array of all the animations on the element. From there you can loop through the array and call the pause() method on each animation.

const circle = document.querySelector(".circle");
const animations = circle.getAnimations();

animations.forEach(animation => {
  animation.pause();
})

Here’s what the full solution would look like, along with a working example if you’re the curious type.

<style>
  .circle {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-color: lightblue;
    margin: auto;
    animation: pulse 1s infinite ease-in-out;
  }

  @keyframes pulse {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(1);
    }
  }
</style>

<div class="circle"></div>
<button class="btn">Pause Animation</button>

<script>
  const btn = document.querySelector(".btn");
  
  btn.addEventListener("click", () => {
    const animations = document.querySelector(".circle")
      .getAnimations();
    
    if (btn.textContent === "Pause Animation") {
      animations.forEach((animation) => {
        animation.pause();
      });
      btn.textContent = "Play Animation";
    } else {
      animations.forEach((animation) => {
        animation.play();
      });
      btn.textContent = "Pause Animation";
    }
  });
</script>

There are other useful properties you can access on the animation object such as currentTime and playbackRate to have even more control over the animation.