useTabOutline: a React hook for better UX and a11y

I wrote this hook to work around the problem of leaving the outline CSS style enabled, where a toggle button’s outline will “stick” on click— e.g. a hamburger menu button.

Eek! The outline stays after I toggle the menu. But if I disable the outline, the button is much less universally accessible for people who rely on the keyboard to navigate. What to do?

Many posts have been written explaining that the most accessibility (“a11y”) friendly solution to this is to disable outlines when the mouse is being used, and enable them when the tab key is used for navigation.

The problem I set out to solve on a code level for our team was how to do this non-invasively — without making global style…

If you’re using media queries in Javascript to do responsive layout, you might be adding listeners to mediaQueryList, a pretty common technique:

const mediaQueryList = window.matchMedia(mediaQuery);
const propagate = (e: MediaQueryListEvent) => {
return e.matches ? handler(true) : handler(false);
mediaQueryList.addEventListener('change', propagate);

However, beware! We recently encountered an ugly problem where older versions of Safari and mobile Safari (12 and before) were throwing an error like property 'addEventListener' does not exist on type 'MediaQueryList' — no joke, this was actually crashing the site!

The problem is that Safari is special — they didn’t upgrade mediaQueryList to use addEventListener as when…

MSIE is finally about dead, with only 2% of global market share remaining. Edge makes developing websites a whole lot easier! I recently ran into a problem where Internet Exploder was so broken, it couldn’t even render a polite “please use another browser” message client-side because it was choking on common.js.

First, if you’re just using vanilla HTML the script looks like this:

For Gatsby I found it was best to inject a script into the HEAD of the page that runs on load. …

There’s a nice Jest plugin for VS Code that adds green or red dots next to each test and even shows which lines fail with inline comments.

Unfortunately, at least at time of writing this, it’s sorely lacking the full interactive, syntax-highlighted goodness of jest --watch. Here’s a trick that makes it easy:

  1. Add a script to your package.json like:
"jest-w": "jest --watch",

2. Open the in-editor Terminal in VS Code (ctrl-`) and type yarn jest-w (or npm run jest-w).

That’s all!

jest watch running in the VS Code in-editor Terminal pane

When you run watch inside the editor, you get the added bonus that console.log shows up in the output for easy debugging. 💥

React Native’s Animated API provides a great way for developers to create performant animations for their iOS and Android apps. It unpacks some of the moving parts typically hidden inside an animation engine, such as raw Animated values that can be tweened directly or interpolated into new values, an extremely versatile and powerful feature. Since it’s a React world, imperative tweens don’t target elements directly, but rather operate on declarative style props like transform.

At Instrument we’ve both loved Animated and found it cumbersome at times, mostly due to to the very way it unpacks so much code into our…

Moses Gunesch

Just another software engineering dad in Portland, Oregon

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store