
Screen Information Detector
Your browser, screen, device, network, and battery details - detected instantly with zero data sent to any server.
Last reviewed: April 2026New to this tool? Click here for instructions
What This Tool Does
The Screen Information Detector reads every display, hardware, and platform property your browser exposes through standard JavaScript APIs — and presents them in a single readable report. The data spans seven categories: screen geometry (CSS resolution, physical pixel count, available area), display characteristics (device pixel ratio, color depth, color gamut, refresh rate, dynamic range), interaction inputs (touch support, pointer type, hover capability), orientation state (portrait, landscape, lock angle), system preferences (color scheme, reduced motion, reduced transparency), browser and OS identity (user agent breakdown, platform, language), and runtime context (timezone, hardware concurrency, memory, network connection class, battery level when permitted).
Every value is read from window.screen, window.matchMedia, navigator, screen.orientation, the Network Information API, or the Battery Status API. The tool issues no network requests, stores nothing in localStorage by default, and transmits zero telemetry. Reload the page and the entire report is recomputed in under 20 milliseconds because every value comes from a synchronous property read or a single asynchronous battery promise. This makes the tool useful as a quick diagnostic any time a layout, image asset, or media query is misbehaving on a specific device — the report tells you exactly what the browser thinks it is rendering on.
Where the data comes from matters, because the same physical attribute is often exposed through multiple APIs with subtly different semantics. window.innerWidth reports the viewport in CSS pixels; window.screen.width reports the full display in CSS pixels; window.visualViewport.width reports the visual viewport (which shifts when the on-screen keyboard appears or pinch-zoom is active). The tool surfaces all three so a misbehaving layout can be traced to the specific axis that has gone wrong.
How to Use It
The detector runs automatically the moment the page finishes loading. There is no input to fill, no button to press, and no preference to configure — the report appears as soon as the JavaScript runtime has executed. The category chips at the top of the page (All Info, Screen, Browser, Network) filter the report to one section at a time, which is useful when you only need the touch and pointer values, or only the network downlink, and don't want to scroll through the full report.
Three workflows benefit most from the report. The first is testing your development environment: confirm that your current browser is running with the DPR, color gamut, and prefers-color-scheme value you expect before debugging a layout. The second is debugging "looks fine on my screen" reports: when a user files a bug that you cannot reproduce, ask them to open this page and send the downloaded report — it captures the exact viewport, DPR, OS theme, and orientation values your CSS is reacting to. The third is verifying Retina and HiDPI asset delivery: open the page on a Retina display, confirm DPR is 2.0 or higher, then load your site in an adjacent tab and use DevTools to check whether your srcset directives are actually delivering the 2x assets your image strategy promises.
The Copy Report and Download Report buttons produce identical plain-text output. Copy is the fastest path when filing a bug ticket — paste the report straight into a Jira comment or GitHub issue. Download generates a screen-info-report.txt file with the same content, which is the right format for attaching to an email or saving to a debugging log alongside browser console output. Both formats include every value the report shows, plus a timestamp, so the data is self-describing when read days later.
Worked Example: MacBook Pro 14" vs iPhone 15 Pro
Two real devices illustrate how the same APIs report dramatically different values depending on the panel beneath them. Both devices use Apple's Liquid Retina XDR technology, both support the Display-P3 wide-gamut color space, and both run at 120 Hz with ProMotion adaptive refresh — but their CSS pixel dimensions, DPR values, and physical pixel counts differ by orders of magnitude.
MacBook Pro 14" (M3, 2023)
The 14-inch MacBook Pro panel measures 3024 by 1890 physical pixels. macOS reports this at a default scaling of "More Space" mode, which yields:
window.innerWidth= 1512 (CSS pixels, full-screen browser)window.innerHeight= 945 (CSS pixels)window.devicePixelRatio= 2.0screen.colorDepth= 30 (10 bits per channel, HDR-capable)matchMedia('(color-gamut: p3)').matches= truematchMedia('(dynamic-range: high)').matches= true- Inferred refresh rate from
requestAnimationFrame= 120 Hz (ProMotion) matchMedia('(prefers-color-scheme: dark)').matches= true (when macOS is set to Dark Appearance)- Touch support: false; pointer: fine; hover: hover
iPhone 15 Pro (A17 Pro)
The iPhone 15 Pro panel measures 1179 by 2556 physical pixels. iOS reports CSS dimensions at a higher DPR to keep text legible at typical viewing distance:
window.innerWidth= 393 (CSS pixels, portrait)window.innerHeight= 852 (CSS pixels, portrait, minus address bar)window.devicePixelRatio= 3.0screen.colorDepth= 24 (Safari does not expose 30-bit even on HDR panels)matchMedia('(color-gamut: p3)').matches= truematchMedia('(dynamic-range: high)').matches= true- Inferred refresh rate from
requestAnimationFrame= 120 Hz (ProMotion) - Touch support: true; pointer: coarse; hover: none; maxTouchPoints: 5
The same browser running the same JavaScript produces wildly different values across these two devices. Note that colorDepth on iOS Safari reports 24 even when the panel is genuinely HDR-capable — the value reflects the framebuffer Safari exposes to JavaScript, not the panel's full capability. Use matchMedia('(dynamic-range: high)') as the authoritative HDR test rather than reading colorDepth.
The diagram below shows how CSS pixels map onto physical pixels at each device's DPR. A single CSS pixel is the unit your stylesheets measure in; a physical pixel is the actual element on the panel. The ratio between them is what window.devicePixelRatio reports.
This is why srcset exists. If your hero image is 1500 CSS pixels wide and you only ship a 1500-physical-pixel asset, it will look soft on a DPR-2.0 MacBook Pro and noticeably blurry on a DPR-3.0 iPhone 15 Pro. The 1x, 2x, and 3x srcset descriptors let the browser pick the right asset for the current DPR — and this tool tells you what that DPR actually is on whatever device you're testing.
Common Use Cases
Responsive Design QA
Every responsive site has a handful of breakpoints — typically at 480px, 768px, 1024px, and 1200px. The Media Query Results section of the report shows which breakpoints currently match, which removes any ambiguity when you are testing whether your max-width: 768px rule is actually active. Pair this with browser DevTools device emulation: emulate an iPhone 14 Pro Max, reload this page, and confirm the viewport width matches the device class you expect. If a breakpoint that should match isn't matching, the report will tell you exactly which side of the boundary you're on.
Debugging Mobile Layout Issues
Mobile-specific bugs are notoriously hard to reproduce on desktop because the viewport, DPR, touch capability, and orientation all differ simultaneously. When a mobile user reports a layout glitch, asking them to open this tool and paste the report into the bug ticket gives you the four pieces of data you actually need: viewport dimensions in CSS pixels, the DPR, whether their browser reports pointer: coarse, and the current orientation. With those four values, you can almost always reproduce the bug in DevTools.
Verifying That Image Assets Match DPR
A site that ships only 1x assets will look noticeably soft on any DPR-2.0 or DPR-3.0 display. This tool reports the DPR; pair it with the Network panel of DevTools and confirm that your srcset directives are actually delivering 2x assets on a 2x screen. If the 2x asset is missing from your network log on a 2x device, your srcset string is wrong — likely a misplaced w descriptor or a missing space between candidates.
Confirming Color Profile (sRGB vs P3 vs Rec.2020)
Color management is one of the most under-debugged areas of front-end engineering. The report's color-gamut media query lines tell you which gamut the browser is willing to honor. If you are serving color: color(display-p3 1 0 0) values and the report shows (color-gamut: p3) = false, the colors are being silently clamped to sRGB — your wide-gamut design is invisible to the user. Wrap P3 colors in an @supports (color: color(display-p3 1 0 0)) block and provide an sRGB fallback so the design degrades gracefully.
Checking Dark Mode Preference
The prefers-color-scheme: dark line tells you what the OS-level theme preference reports. This is the single source of truth for "should my site default to dark mode" — checking localStorage for a stored preference is a second layer on top, not a replacement. The report also surfaces prefers-reduced-motion and prefers-reduced-transparency, both of which should gate any animation or backdrop-filter effects you ship.
Measuring Viewport vs Window Size Differences
On mobile Safari, the visual viewport and the layout viewport diverge when the address bar collapses on scroll. The report shows both window.innerHeight (layout) and the screen height (full display) so you can see the gap. A 100vh CSS value uses the layout viewport, which on iOS Safari is taller than the visible area when the address bar is expanded — leading to the well-known "buttons hidden below the fold on first paint" bug. Use 100dvh (dynamic viewport height) instead when targeting modern Safari.
Edge Cases and Quirks
Fractional DPR Values
Microsoft Surface Pro devices report a DPR of 1.25 or 1.5 at default Windows scaling. Some Chromebooks report 1.33. These fractional ratios were not anticipated by the original 2x asset strategy, which is why srcset uses w descriptors instead of x descriptors in most modern image strategies — the browser picks the best candidate based on the actual rendered pixel width, not a round-numbered DPR multiplier.
CSS Pixel Does Not Equal Physical Inch at All Scales
The CSS specification defines one CSS pixel as 1/96 of an inch at a 28-inch viewing distance — but only at the default zoom level. Browser zoom rescales the CSS pixel directly. At 200% zoom, one CSS pixel still occupies the same angular size in the user's field of view, but it now covers twice as many physical pixels (or, on a fixed-DPR display, twice the physical area). The "1/96 inch" definition is a starting reference, not an invariant.
Touch and Mouse Devices Report Both
Modern hybrid devices — Surface Pro, iPad with Magic Keyboard, Chromebook touchscreens — report both pointer: fine and pointer: coarse as matches via any-pointer media queries. Designing exclusively for one or the other on these devices breaks the experience for the other input mode. The hover: hover query is the more reliable test for "user has a mouse-like pointing device available right now."
Orientation Lock vs Free Rotation
screen.orientation.type reports the current orientation, but screen.orientation.lock() is what actually pins it — and lock() is only available to apps in fullscreen mode in most browsers. A regular web page can read orientation but cannot prevent rotation. If your layout breaks badly in one orientation, hide content rather than attempting to lock — the lock will silently fail in non-fullscreen contexts.
Browser Zoom Changes Effective DPR
As described in the FAQ below, browser zoom is implemented by rescaling the CSS pixel. Zooming to 200% on a DPR-1.0 display produces window.devicePixelRatio = 2.0 — visually equivalent to a native 2x display. If your code branches on DPR, it will branch on zoom level too. Detect zoom specifically by comparing devicePixelRatio against a baseline captured at page load.
iOS Safari Viewport-Fit Quirks
iOS Safari has historically reported window.innerHeight in ways that conflict with the visible viewport. Modern iOS exposes 100dvh, 100svh, and 100lvh CSS units to disambiguate dynamic, small, and large viewport heights. Older iOS versions only support 100vh, which corresponds to the largest viewport (with the address bar collapsed) — producing the famous "content hidden under the address bar" bug on first paint. Use the visualViewport API for the most accurate live viewport measurement.
Hi-DPI Linux X11 Misreporting
X11 desktops on Linux historically did not have first-class HiDPI support. Many X11 configurations report a DPR of 1.0 even on a 4K panel where the OS is rendering at a non-integer scale via X resources. Wayland fixes most of this, but if you are debugging a Linux user's report, ask whether they are on X11 or Wayland — the values they see may not match what the panel is actually doing.
Behind the Scenes
The CSS Object Model (CSSOM)
The values you read from window.innerWidth, window.screen.width, and window.matchMedia are all surfaced by the CSS Object Model — the JavaScript-accessible representation of CSS state. The CSSOM is what makes runtime style introspection possible; it is also what powers getComputedStyle(), document.styleSheets, and every CSS-related Web API. Reading a CSSOM property is synchronous and fast because the values are derived from the layout tree, which the browser maintains continuously.
Device Pixel Ratio: A Brief History
Apple introduced the concept publicly with the iPhone 4 in 2010. The iPhone 4 doubled the pixel density of the iPhone 3GS in each dimension — quadrupling the total pixel count — and Apple wanted apps written for the 3GS to continue working without modification. The solution was to introduce a second pixel coordinate system: CSS pixels, which remained at the older density, and physical pixels, which were now four times as numerous. Mobile Safari exposed the ratio between them via window.devicePixelRatio. The Android ecosystem adopted the same model shortly after, and by 2013 every major browser supported it. matchMedia('(min-resolution: 2dppx)') was added as the standardized CSS-side test.
The CSS Reference Pixel Definition
The CSS specification defines the reference pixel as the visual angle of one pixel on a 96 DPI device viewed from a distance of 28 inches. That is approximately 0.213 millimeters at the viewing surface, or about 0.0026 degrees of visual angle. This definition is what makes CSS pixels device-independent: a CSS pixel on a phone held close to your face occupies the same angular size as a CSS pixel on a desktop monitor viewed from arm's length — even though the absolute physical sizes differ. Whether a browser actually honors this reference at all viewing distances is another matter; most browsers approximate it by assuming a fixed mapping rather than measuring real viewing distance.
Color Spaces in CSS Color Module Level 4
The CSS Color Module Level 4 specification introduces explicit color space syntax: color(display-p3 1 0 0), color(rec2020 0.5 0.5 0.5), and the oklch() and lab() perceptual color functions. The (color-gamut: p3) and (color-gamut: rec2020) media queries let you detect support before serving wide-gamut values. Browsers that support the color module but not the queried gamut will report false; browsers that do not support the module at all will fail the query silently. The report's media query list reads both, so you can see exactly which gamuts the current browser claims.
Refresh Rate Detection via requestAnimationFrame
Browsers do not expose monitor refresh rate as a direct property. The standard inference technique is to schedule a requestAnimationFrame callback, record performance.now(), schedule the next callback inside the first, and compute the delta. A 16.67 ms delta indicates 60 Hz; 8.33 ms indicates 120 Hz; 4.17 ms indicates 240 Hz. Averaging over 60 frames smooths out scheduler jitter. The technique only works while the tab is in the foreground — browsers throttle requestAnimationFrame in background tabs to 1 Hz to save battery, which makes the inferred rate meaningless until the tab is brought back to focus.
API Comparison: devicePixelRatio vs screen vs visualViewport vs matchMedia
Four overlapping APIs report screen and viewport information, and they are not interchangeable. The table below summarizes when each is the correct choice.
| API | Reports | Best Used For |
|---|---|---|
window.devicePixelRatio |
Single float — ratio of physical to CSS pixels, with zoom factored in | Picking 1x / 2x / 3x image assets, canvas backing-store sizing |
window.screen.* |
Full display dimensions in CSS pixels, color depth, orientation | Detecting the user's device class regardless of window size |
window.innerWidth / innerHeight |
Layout viewport in CSS pixels (excludes browser chrome) | CSS breakpoint logic, deciding mobile vs desktop layout |
window.visualViewport |
Visual viewport — shifts with on-screen keyboard and pinch-zoom | Positioning floating UI relative to what the user actually sees |
window.matchMedia(query) |
Boolean match for any CSS media query, with live change events |
Reading prefers-color-scheme, pointer type, hover, gamut, dynamic-range |
screen.orientation |
Orientation type and angle, with change events |
Reacting to portrait/landscape rotation on mobile |
Use matchMedia wherever a CSS media query exists for the property — the change events fire reliably and the API is the most future-proof. Reserve devicePixelRatio for asset-selection logic where you genuinely need the numeric ratio. Use visualViewport only when the visual viewport diverges from the layout viewport — which is rare on desktop and common on mobile with a virtual keyboard open.
Frequently Asked Questions
window.devicePixelRatio.window.screen.width reports CSS pixels, which on a Retina display are scaled by the device pixel ratio. For a MacBook Pro 14 inch with a native 3024x1890 panel and a default DPR of 2.0, CSS pixels work out to 1512x945. Multiply the CSS dimensions by window.devicePixelRatio to recover the physical pixel count: 1512 × 2 = 3024, 945 × 2 = 1890.window.innerWidth is the width of the browser viewport in CSS pixels, excluding browser chrome and scrollbars. window.screen.width is the width of the entire display in CSS pixels, regardless of how the browser window is positioned or sized. Use innerWidth for layout decisions; use screen.width when you need to know the device class. On a maximized window with no taskbar overlap they often match — but never assume that's guaranteed.matchMedia('(color-gamut: p3)') to detect Display-P3 capability on Apple silicon and recent Android devices, and serve a wider-gamut variant when available. Wrap wide-gamut color values inside an @supports (color: color(display-p3 1 0 0)) block so older browsers fall back to sRGB without loading the wider-gamut assets.matchMedia('(dynamic-range: high)').matches returns true on HDR-capable displays. The video-dynamic-range query is the legacy form and is still supported in some browsers. Color depth is not a reliable HDR indicator on its own — screen.colorDepth reports the bit depth of the framebuffer, which can be 30-bit or 48-bit on an SDR panel just as well as on an HDR one.window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', handler). Some embedded browsers and very old versions return no-preference regardless of the OS setting.window.devicePixelRatio returns the effective ratio after zoom, so the value changes whenever the user zooms. To detect zoom specifically, you can compare devicePixelRatio against the initial value captured at page load.requestAnimationFrame timestamps. Schedule a callback, record the timestamp, schedule the next callback, and compute the delta. The reciprocal of that delta is the refresh rate: a 16.67 ms delta corresponds to 60 Hz, an 8.33 ms delta to 120 Hz, and a 4.17 ms delta to 240 Hz. Average over 60 frames or so to filter jitter. Some browsers expose Screen.update_rate behind a flag, but it is not yet standardized.