Original article - written by Marko Ilic
Media query is a CSS technique introduced in CSS3.
CSS media queries are a core ingredient in any responsive design. They’re a great way to apply different styles to different contexts.
The old way to detect media queries in JS is using window innerWidth as sample code below:
function checkMediaQuery() {
// If the inner width of the window is greater then 768px
if (window.innerWidth > 768) {
doResponsiveThings();
}
}
window.addEventListener('resize', checkMediaQuery);
Using matchMedia()
To determine if the document matches the media query string in JavaScript, we use the matchMedia() method. Even though it’s officially part of the CSS Object Model View Module specification which is in Working Draft status, the browser support for it is great going as far back as Internet Explorer 10 with 98.6% global coverage.
The usage is nearly identical to CSS media queries. We pass the media query string to matchMedia() and then check the .matches property.
const mediaQuery = window.matchMedia('(min-width: 768px)')
The defined media query will return a MediaQueryList object. It is an object that stores information about the media query and the key property we need.
const mediaQuery = window.matchMedia('(min-width: 768px)')
// Check if the media query is matched
if (mediaQuery.matches) {
doResponsiveThings();
}
That’s the basic usage for matching media conditions in JavaScript. But there’s more to it. For example, if we were change the window size below our target window size, nothing updates the way it will with CSS right out of the box.
Listen for changes
MediaQueryList has an addListener() (and the subsequent removeListener()) method that accepts a callback function that’s invoked when the media query status changes. we can fire additional functions when the conditions change, allowing us to “respond” to the updated conditions.
const mediaQuery = window.matchMedia('(min-width: 768px)')
function handleTabletChange(e) {
// Check if the media query is true
if (e.matches) {
doResponsiveThings();
}
}
// Register event listener
mediaQuery.addListener(handleWindowChange)
// Initial check
handleWindowChange(mediaQuery)
We explored how matchMedia() allows us to define media conditions and examined the MediaQueryList object. We also saw the “old” way of doing things by listening for resize events on the window. While it’s still widely used and a totally legit way to respond to changes to the size of the window.innerWidth, it’s unable to perform checks on advanced media conditions.
Looking at the performance impact comparing with the old way:
More about @media queries - A Complete Guide to CSS Media Queries - by Andrés Galante
== Update from @rvxlab comment
MediaQueryList.addListener is marked as deprecated, MediaQueryList extends from EventTarget so you can use addEventListener instead. Except for Safari 13 & earlier we can do fallback condition as below:
// Register event listener
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handleWindowChange);
} else {
mediaQuery.addListener(handleWindowChange);
}
Top comments (2)
Mind you that
MediaQueryList.addListener
is deprecated,MediaQueryList
extends fromEventTarget
so you can useaddEventListener
instead.Notable exception being Safari 13 and earlier, which doesn't do this.
The ideal solution is to check for
addEventListener
and fall back toaddListener
when it's not available:Thanks for the update solution!