Encoding data for POST requests #

I'm grateful that Jake Archibald has taken the time to cover some of the browser's built-in APIs for managing form data. I've been building forms for years, and I still learned a lot from this post, particularly around FormData and how fetch handles different body object types.

On a tangentially related note, I've been tootling around with remix.run for a personal project, and one of the core design decisions is to use native browser APIs whenever possible. It really is quite nice to be able to take a <form> element and convert it to a fetch request with minimal effort:

fetch(form.action, {
  method: form.method,
  body: new FormData(form)
})

The Future of CSS #

Miriam Suzanne gave an excellent talk about the future of CSS, outlining three of the newer working group proposals and specifications.

Specifically:

  • cascade layers
  • scoped styles
  • container queries

Having spent much of my career working on bespoke websites with drastically different needs and equally different approaches to design, it's gratifying to have such a clear view into the future of CSS. Having any one of the three features would be an enormous win for CSS architecture, but all three together? Revolutionary.

Modern HTML Boilerplate #

Manuel Matuzovic has an excellent write-up of his modern HTML boilerplate.

I really enjoy reading these back-to-the-basics type posts because I almost always learn about some new feature that I wasn't aware of before. This post was no exception. In particular there's a lot to know about icons and image previews that I now want to integrate into all of my projects.

TIL: node.isConnected exists #

Shout out to Lea Verou for sharing Node.isConnected. I've had a few cases where I've needed to determine if a node is in the DOM. I've usually written something along the lines of:

const inDOM = (node) => {
  for (let n = node; n; n = n.parentNode) {
    if (n === document) {
      return true;
    }
  }
  return false;
};

Having a native property for this will be helpful.

My Focus

Where did you go?
I could have sworn
you were here a minute ago.

I looked at my phone
to check a notification,
only for a minute.

Only when I looked up
—half an hour later—
did I realize you were gone.

Web Animation Gotchas #

This is an excellent overview of using the Web Animation API.

I meant to share this a month ago when I first saw it, but it came up again recently when I was making some animation improvements to a website I've been working on, so there's no time like the present.

I made some minor changes to the animateTo function included in the video for my own purposes, so the snippet I use is along the lines of:

function animateTo(element, keyframes, options) {
  let cleanup = () => {};
  return new Promise((resolve, reject) => {
    try {
      const animation = element.animate(
        keyframes,
        {
          ...options,
          fill: 'both',
          signal: undefined
        }
      );

      const finish = () => {
        try {
          animation.commitStyles();
          animation.cancel();
          resolve();
        } catch (e) {
          // handle browsers that don't support `Animation.prototype.commitStyles`
          reject(e);
        }
      };
      animation.addEventListener('finish', finish);

      // While the animation is not exposed through `animateTo`,
      // animations can still be cancelled via the `signal` option,
      // or when accessed from `Element.prototype.getAnimations`
      const cancel = () => reject();
      animation.addEventListener('cancel', cancel);

      // Add support for AbortController
      const signal = options.signal;
      const abort = () => animation.cancel();
      if (signal) {
        signal.addEventListener('abort', abort);
      }

      cleanup = () => {
        animation.removeEventListener('finish', finish);
        animation.removeEventListener('cancel', cancel);
        if (signal) {
          signal.removeEventListener('abort', abort);
        }
      }
    } catch (e) {
      // handle older browsers that don't have `Element.prototype.animate`
      reject(e);
    }
  }).finally(cleanup);
}

More than Coding #

I meant to share this a couple months ago when I first read it. It's an excellent breakdown of some of the differences between software engineer levels and the type of work expected.

As a tangent, Bonnie Eisenman uses the following roles for the various different levels:

  • junior
  • midlevel
  • senior
  • staff

I like that Bonnie chose to label the various levels numerically. I prefer to use numeric levels when possible, as it helps to avoid some bias when someone switches to tech late in their career and takes on a "junior" role. Unfortunately there's no real standard for numeric levels.

My preferred labels are along the lines of:

  • level 0: intern/co-op
  • level 1: junior
  • level 2: midlevel
  • level 3: senior
  • level 4: staff

Anyway, go read Bonnie's post.

Hacking the Prime Minister #

Alex's "Do not get arrested challenge 2020" is the best thing I've read all week.

Somewhere around:

I called at least 30 phone numbers, to say nothing of The Emails. If you laid all the people I contacted end to end along the equator, they would die, and you would be arrested.

I laughed so hard I nearly fell out of my chair.

James Hong - Great Big Story #

I've seen James Hong's performances many times, but they only account for a tiny portion of his extraordinary number of roles.

I first started recognizing him after his voice acting for Covetous Shen in Diablo III. He really leaned into the rich texture of his voice for Shen, which made Shen stand out as particularly memorable to me. Every time James appears in a TV show or movie I'm watching, I think to myself "It's Covetous Shen!"