Responsive-layout gotcha: watch out for older Safari versions!

Moses Gunesch
2 min readMar 6, 2021

--

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 most folks did. The MDN docs say that although it’s deprecated it’s also:

“… retained for backwards compatibility purposes. Older browsers should use addListener instead of addEventListener since MediaQueryList only inherits from EventTarget in newer browsers.”

So we have one of those unfortunate cases where we need to handle past and future cases. Here’s an easy way to do that:

mediaQueryList.hasOwnProperty('addEventListener')
? mediaQueryList.addEventListener('change', propagate)
: mediaQueryList.addListener(propagate);
// later when you want to clean up
mediaQueryList.hasOwnProperty('removeEventListener')
? mediaQueryList.removeEventListener('change', propagate)
: mediaQueryList.removeListener(propagate);

That’s all, come see us at Y’all!

TL;DR

To be sure we never miss this, we’ve built a useMedia React hook that lets you pass in a media-query string and then handles subscribe/cleanup for you — and because we do SSG/SSR in Gatsby and Next.js, it only does this when rendering on the client. Then to ensure we have a single source of truth for our breakpoints, we :export them as fully formatted media queries from sass, like mq_mobile: unquote(‘screen and (max-width: #{$bp-mobile})’).

It’s a pretty tight system — if you’re interested let me know and I’ll share it sometime! ⭐️

--

--

Moses Gunesch
Moses Gunesch

Written by Moses Gunesch

Just another software engineering dad in Portland, Oregon

Responses (1)