Screen Information Detector

Your browser, screen, device, network, and battery details - detected instantly with zero data sent to any server.

Last reviewed: April 2026

New to this tool? Click here for instructions

Loading screen information...

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.0
  • screen.colorDepth = 30 (10 bits per channel, HDR-capable)
  • matchMedia('(color-gamut: p3)').matches = true
  • matchMedia('(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.0
  • screen.colorDepth = 24 (Safari does not expose 30-bit even on HDR panels)
  • matchMedia('(color-gamut: p3)').matches = true
  • matchMedia('(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.

CSS Pixels vs Device Pixels vs Physical Inches Across Three DPR Values A diagram comparing one CSS pixel to its physical pixel grid at DPR 1.0, 2.0, and 3.0. At DPR 1.0 one CSS pixel maps to one physical pixel. At DPR 2.0 one CSS pixel maps to a 2x2 grid of four physical pixels, typical of MacBook Pro Retina displays. At DPR 3.0 one CSS pixel maps to a 3x3 grid of nine physical pixels, typical of iPhone 15 Pro Super Retina XDR displays. All three CSS pixels occupy the same one-ninety-sixth of an inch at reference viewing distance. One CSS Pixel at Different Device Pixel Ratios All three squares occupy the same physical size (1/96 inch at reference viewing distance) DPR 1.0 1 CSS px = 1 physical px Standard density e.g. 1080p monitor Total: 1 device pixel DPR 2.0 1 CSS px = 2x2 physical px Retina / HiDPI MacBook Pro 14" Total: 4 device pixels DPR 3.0 1 CSS px = 3x3 physical px Super Retina XDR iPhone 15 Pro Total: 9 device pixels Why all three squares are the same size: The CSS reference pixel is defined as 1/96 of an inch at 28 inches viewing distance. The DPR scales the panel up so each CSS pixel still occupies the same angular size in your field of view — but is drawn with more physical pixels for sharper rendering. Reading it from JavaScript: window.devicePixelRatio // 1.0, 2.0, 3.0 Practical impact on a 1500 CSS-pixel-wide viewport DPR 1.0 → 1500 physical px DPR 2.0 → 3000 physical px DPR 3.0 → 4500 physical px Same CSS layout, three different image asset sizes needed for 1x, 2x, 3x srcset coverage

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

Device pixel ratio (DPR) is the ratio of physical pixels on the display to CSS pixels reported to the browser. A DPR of 2.0 means each CSS pixel is rendered using a 2x2 grid of physical pixels — four physical pixels per CSS pixel. The ratio was introduced by Apple in 2010 with the iPhone 4 Retina display and has since become a standard property of every modern display. Read it via window.devicePixelRatio.
The product page reports physical pixels — the actual pixels on the panel. 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.
Target sRGB as your baseline because it is universally supported and is the gamut all browsers assume in the absence of an explicit color profile. Use 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.
Use the dynamic-range media query: 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.
On modern browsers and operating systems, yes. macOS Mojave introduced system-wide dark mode in 2018, Windows 10 followed shortly after, and iOS and Android both expose the preference. The query returns the user's OS-level theme preference at the time of the call. To react to live changes, attach a change listener: window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', handler). Some embedded browsers and very old versions return no-preference regardless of the OS setting.
Browser zoom is implemented by rescaling the CSS pixel itself relative to physical pixels. At 200% zoom on a DPR-1.0 display, each CSS pixel is rendered using a 2x2 grid of physical pixels — exactly the same arrangement as a native DPR-2.0 display. 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.
There is no direct API for monitor refresh rate, but you can infer it from 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.