Media queries are not limited to CSS. JavaScript can also react to them. This can be very useful when building applications.
If you're looking for an existing solution for using media queries in JavaScript, checkout my small library mediaq.
The window.matchMedia API
Browsers expose the window.matchMedia method. It takes a media query as an argument and returns a MediaQueryList
object.
const mediaQueryList = window.matchMedia("only screen and (max-width: 600px");
Checking if a media query matches
Once created, a MediaQueryList
object has the boolean property matches
. Use that property to check, at any time, if the media query is matching.
if (mediaQueryList.matches) {
console.log("It matches!");
} else {
console.log("It doesn't match.");
}
Listening for updates
Instead of checking if the MediaQueryList
object matches, you can attach an event listener to it. The listener will trigger whenever the media query matches or stops matching (the window is resized, the device orientation changes etc.).
Since MediaQueryList
inherits EventTarget
, listening to the events it fires is very straightforward.
const listener = (event) => {
console.log(event.matches ? "It matches!" : "It doesn't match.");
};
mediaQueryList.addEventListener("change", listener);
Removing a listener is also as easy
mediaQueryList.removeEventListener("change", listener);
Internet explorer and Safari < 14 handle those event listeners differently. They use addListener
/removeListener
instead.
To support those browsers as well, you can conditionally call the correct method.
const listener = (event) => {
console.log(event.matches ? "It matches!" : "It doesn't match.");
};
if (mediaQueryList.addEventListener) {
mediaQueryList.addEventListener("change", listener);
} else {
mediaQueryList.addListener(listener);
}
// For removal
if (mediaQueryList.removeEventListener) {
mediaQueryList.removeEventListener("change", listener);
} else {
mediaQueryList.removeListener(listener);
}
You can read more about browser compatibility.
Why use media queries with JavaScript?
When applied through CSS, media queries help create responsive layouts. They also allow hiding certain elements on the web page and loading higher/lower resolution background pictures.
In some scenarios that is not enough. That's when JavaScript can be used to optimize the webpage further.
Imagine a component of your webpage is computationally heavy and you decide you don't need it to display on smaller screens. In CSS, you can easily hide it, but it would still exist as part of your DOM and could still weigh down the performance of your web application.
@media only screen and (max-width: 480px") {
.component {
display: none; /* The component is hidden but is still part of the webpage.*/
}
}
In JavaScript, on the other hand, you could decide whether or not to append the element to the document.
const mediaQueryList = window.matchMedia("only screen and (max-width: 480px");
if (!mediaQueryList.matches) {
// Create/Append the element here
}
Another use case is loading certain scripts for certain screen sizes. If you application uses large graphing libraries, you can choose to include them only on desktop-size devices, where the graphs are being displayed.
const mediaQueryList = window.matchMedia("only screen and (min-width: 768px");
if (mediaQueryList.matches) {
const script = document.createElement("script");
script.src = "path to JavaScript script";
document.body.appendChild(script);
}
JavaScript can detect screen resolution without using media queries. This can work for one-time checks. Listening to updates with the resize
event on the window object can be expensive. Using media queries is much more efficient.
Top comments (7)
Often you are using a ux framework, and then would prefer to bind to the framework instead of hard coding the breakpoints. In that case, something like this is much better:
gist.github.com/wparad/6687a200ebb...
Thanks for sharing. There are indeed multiple solutions to this problem.
Thanks for the solution, but its probably very inefficient because of multiple 'getComputedStyle' calls.
It's actually very effective without a problem.
getComputedStyle() forces layout recalculation. While its ok for simple cases, in general, its a perfomance bottleneck.
Might be useful (what forces layout reflow):
gist.github.com/paulirish/5d52fb08...
Nice this is great.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.