Unbiased Decisions

When you use data to make "unbiased" decisions, the questions you ask and the data you choose are the bias.

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.