Use the browser’s window.matchMedia() method. Pass a media-query string, then read the returned MediaQueryList.matches boolean. Add that object’s change listener when the result must stay current as the browser environment changes.
The smallest useful detector is:
const query = window.matchMedia("(width <= 600px)");
console.log(query.matches);
What a media query detector actually tells you
CSS media queries test viewport values and browser or device features before conditionally applying styles. They can control responsive layouts, orientation-specific presentation, print output, color scheme, motion preferences and input capabilities. A JavaScript detector evaluates one query that you provide in the current document context; it does not automatically discover every media query written in every stylesheet. MDN’s media-query guide describes the CSS side, while the matchMedia() reference documents the browser API.
If matches is true, the current document matches that expression under its present browser conditions. If it is false, it does not. For example, a width query describes the queried document’s current viewport condition, not a permanent characteristic of a phone, laptop or monitor.
Run a one-time check
Use a one-time read when your code only needs the answer at the moment it runs—for example, to choose an initial component layout.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
const query = window.matchMedia("(width <= 600px)");
if (query.matches) {
console.log("The document is at or below 600 CSS pixels wide.");
} else {
console.log("The document is wider than 600 CSS pixels.");
}
The argument is a normal media-query expression. Media features must be parenthesized, as in (width <= 600px) or (orientation: landscape). Media types such as screen and logical operators such as and, or and not do not need their own parentheses.
Combine a media type and features
const query = window.matchMedia("screen and (orientation: landscape) and (width >= 900px)");
console.log(query.matches ? "Landscape desktop layout" : "Other layout");
The boolean is evaluated by the browser, so you do not need to duplicate CSS’s comparison logic in JavaScript. Keep the string identical to the condition whose state you need to observe.
Keep the detector current with the change event
A one-time read becomes stale when a user resizes a window, rotates a device, changes a relevant browser setting or enters a different presentation mode. Subscribe to the returned MediaQueryList to react when its matching state changes. MDN recommends event listening instead of repeatedly polling the result. See the change event reference.
const query = window.matchMedia("(width <= 600px)");
function showMatch(event) {
console.log(event.matches ? "matches" : "does not match");
}
showMatch(query); // Report the initial state.
query.addEventListener("change", showMatch);
The initial call is important: a change event reports transitions, not the state that existed before the listener was attached. The event’s matches property is the new boolean value.
Update an element instead of logging
const query = window.matchMedia("(width <= 600px)");
const status = document.querySelector("#breakpoint-status");
function render(event) {
status.textContent = event.matches
? "Compact layout is active"
: "Wide layout is active";
status.dataset.matches = String(event.matches);
}
render(query);
query.addEventListener("change", render);
When the component is destroyed, remove the same function reference:
Rank #2
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
query.removeEventListener("change", render);
Removing the listener prevents a detached component from continuing to receive updates.
Build a reusable media-query detector
Wrapping the API in a small helper gives each component the same lifecycle and makes cleanup explicit.
export function watchMediaQuery(queryText, onChange) {
const mediaQuery = window.matchMedia(queryText);
const handleChange = (event) => onChange(event.matches, event);
handleChange(mediaQuery);
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}
const stopWatching = watchMediaQuery(
"(prefers-reduced-motion: reduce)",
(reduced) => {
document.documentElement.classList.toggle("reduced-motion", reduced);
}
);
// Call stopWatching() when the owning component is removed.
The callback receives the boolean first and the event second, while the returned function provides deterministic cleanup. If your project must support an older browser, verify its supported versions before relying on the event form.
Useful queries to detect
The detector accepts any valid media-query expression. These examples show common questions a responsive interface may need to answer:
| Purpose | Query | Meaning when matches is true |
|---|---|---|
| Compact width | (width <= 600px) |
The current document width is 600 CSS pixels or less. |
| Landscape orientation | (orientation: landscape) |
The document is in landscape orientation. |
| Dark color scheme | (prefers-color-scheme: dark) |
The browser currently prefers a dark color scheme. |
| Reduced motion | (prefers-reduced-motion: reduce) |
The user has requested reduced motion. |
| Fine pointer | (pointer: fine) |
The primary pointer has fine accuracy. |
| Hover capability | (hover: hover) |
The primary input can hover. |
| Print presentation | print |
The document is being evaluated for print media. |
Use the same expression in CSS and JavaScript where possible. A shared breakpoint value prevents a stylesheet and a script from disagreeing because one uses 600 pixels and the other uses 601.
Rank #3
Interpret syntax correctly
Parentheses and operators
Write feature tests with parentheses: (width >= 900px), (orientation: portrait) and (hover: none). A type-only query such as screen is valid without parentheses. Logical combinations follow CSS media-query grammar:
const query = window.matchMedia(
"not print and (width <= 700px)"
);
Boolean interpretation
Do not label a result as “this device is mobile” or “this model is a tablet.” A more accurate message is “this document matches the query under its current browser conditions.” Viewport size, orientation and user preferences can change while the same page remains open.
One query at a time
matchMedia() evaluates the string you pass. It is not a stylesheet parser and does not return a list of breakpoints. If an application has three meaningful layout states, create three explicit MediaQueryList objects or define a small map of named queries.
const queries = {
small: window.matchMedia("(width <= 600px)"),
medium: window.matchMedia("(width > 600px) and (width < 1024px)"),
large: window.matchMedia("(width >= 1024px)")
};
function currentLayout() {
if (queries.small.matches) return "small";
if (queries.medium.matches) return "medium";
return "large";
}
console.log(currentLayout());
If several query states can change independently, attach a listener to each and recompute the derived state in one function.
Compatibility and feature checks
MDN marks matchMedia() and the MediaQueryList.matches property as widely available, with cross-browser availability reported since July 2015. MDN likewise marks the change event as widely available and reports availability since September 2020. Those dates are MDN’s compatibility summaries, not a guarantee for every embedded browser or legacy version. Check the browser versions your project actually supports. See the matches reference and the MediaQueryList reference.
Rank #4
If you need a defensive check before running browser-only code:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteif (typeof window !== "undefined" && typeof window.matchMedia === "function") {
const query = window.matchMedia("(width <= 600px)");
console.log(query.matches);
}
This guard is useful in code that may be imported during server-side rendering, where window is not available. It does not emulate a browser result; it simply waits until the code runs in a document environment.
Troubleshooting a detector
The result is always false
- Check the expression. A feature test needs parentheses. Use
(width <= 600px), notwidth <= 600px. - Check the document context. The result belongs to the document in which the code runs and reflects its current conditions.
- Check the media type. A query such as
printwill not match ordinary screen presentation.
The displayed value never changes
- Attach a listener. Reading
matchesonce cannot update your UI later. - Call the renderer once. The listener handles transitions; it does not replace the initial render.
- Use the same callback reference for cleanup. Passing a newly created function to
removeEventListener()does not remove the original listener.
The script throws before evaluating the query
- Run it in a browser document. Guard access to
windowin server-rendered or non-browser code. - Check the query string for JavaScript syntax errors. Keep the media query inside a quoted string and escape only what JavaScript requires.
The script and CSS disagree at a breakpoint
- Compare the exact strings, units and comparison boundaries. Decide whether a boundary belongs to the smaller or larger range, then use the same rule in both places.
- Remember that a result can change after orientation, viewport or relevant preference changes. Do not cache a breakpoint decision permanently if the interface is expected to adapt.
Performance and lifecycle guidance
For a single decision, one matchMedia() call and one matches read are sufficient. For a live interface, event-driven updates avoid a timer that repeatedly polls the browser. Keep handlers small: update the affected component or state, rather than rebuilding the whole page on every transition.
Centralize shared queries when several components need the same breakpoint, and remove listeners when those components unmount. This avoids duplicate work and prevents updates to objects that are no longer visible. If your application tracks many independent features, use a registry that owns their listeners and exposes one cleanup operation.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is to collect screenshots of responsive states for review or automation rather than inspect a boolean in JavaScript, ScreenshotNeo provides a website screenshot API and MCP server. It can capture full pages, use device presets or custom viewports, and return PNG, JPEG, WebP or PDF. It does not replace matchMedia(); it gives you rendered evidence at the viewport and settings you choose.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Best Value
One GET request is enough (see the ScreenshotNeo API documentation):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing state with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
The Free plan includes 1,000 screenshots per month without a card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to start.
FAQ
Does the change event fire on every resize step?
No. It reports when the media query’s matching result changes. A resize that remains on the same side of a breakpoint does not create a transition for that query.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Can I monitor a print query?
Yes. Pass print to matchMedia() like any other media-query expression and observe its boolean. Treat the result as the document’s current print-media evaluation, not as a permanent page property.
What is the best way to test several breakpoints?
Create one named MediaQueryList per breakpoint, evaluate their initial matches values, and attach listeners that recompute the active layout. This keeps each condition explicit and makes cleanup manageable.
Frequently Asked Questions
Does the change event fire on every resize step?
No. It fires when the query changes from matching to not matching, or vice versa.
Can I monitor a print query?
Yes. Pass print to matchMedia() and observe its boolean state.
Free tools Windows power users keep installed
One-click scans. No signup required.
What is the best way to test several breakpoints?
Create one named MediaQueryList for each breakpoint, evaluate the initial states, and attach listeners that recompute the active layout.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

