The devicePixelRatio
of Window
interface returns the ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device.
This value could also be interpreted as the ratio of pixel sizes: the size of one CSS pixel to the size of one physical pixel. In simpler terms, this tells the browser how many of the screen's actual pixels should be used to draw a single CSS pixel.
This is useful when dealing with the difference between rendering on a standard display versus a HiDPI or Retina display, which use more screen pixels to draw the same objects, resulting in a sharper image.
You can use window.matchMedia()
to check if the value of devicePixelRatio
changes (which can happen, for example, if the user drags the window to a display with a different pixel density). See the example below.
A double-precision floating-point value indicating the ratio of the display's resolution in physical pixels to the resolution in CSS pixels. A value of 1 indicates a classic 96 DPI (76 DPI on some platforms) display, while a value of 2 is expected for HiDPI/Retina displays. Other values may be returned as well in the case of unusually low resolution displays or, more often, when a screen has a higher pixel depth than double the standard resolution of 96 or 76 DPI.
A <canvas>
can appear too blurry on retina screens. Use window.devicePixelRatio
to determine how much extra pixel density should be added to allow for a sharper image.
HTML
<canvas id="canvas"></canvas>
JavaScript
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const size = 200;
canvas.style.width = `${size}px`;
canvas.style.height = `${size}px`;
const scale = window.devicePixelRatio;
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);
ctx.scale(scale, scale);
ctx.fillStyle = "#bada55";
ctx.fillRect(10, 10, 300, 300);
ctx.fillStyle = "#ffffff";
ctx.font = "18px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const x = size / 2;
const y = size / 2;
const textString = "I love MDN";
ctx.fillText(textString, x, y);
In this example, we'll set up a media query and watch it to see when the device resolution changes, logging the new resolution.
HTML
<div id="container">
<p>
This example demonstrates the effect of zooming the page in and out
(or moving it to a screen with a different scaling factor) on the
value of the <code>devicePixelRatio</code> property.</p>
<p>Try it and watch what happens!</p>
</p>
</div>
<div id="output"></div>
CSS
body {
font:
22px arial,
sans-serif;
}
#container {
border: 2px solid #22d;
margin: 1rem auto;
padding: 1rem;
background-color: #a9f;
}
JavaScript
The string mqString
is set to a media query which checks to see if the current display resolution matches a specific number of device dots per px
.
The media
variable is a MediaQueryList
object that's initialized with the media query string. When the result of running mqString
against the document changes, the media
object's change
event fires, and the code logs the new resolution.
Note that every time the resolution changes, the example has to create a new media query, based on the new resolution, and a new MediaQueryList
instance.
let remove = null;
const output = document.querySelector("#output");
const updatePixelRatio = () => {
if (remove != null) {
remove();
}
const mqString = `(resolution: ${window.devicePixelRatio}dppx)`;
const media = matchMedia(mqString);
media.addEventListener("change", updatePixelRatio);
remove = () => {
media.removeEventListener("change", updatePixelRatio);
};
output.textContent = `devicePixelRatio: ${window.devicePixelRatio}`;
};
updatePixelRatio();
Result
To test the example, try zooming the page in and out, and note the difference in the logged value of devicePixelRatio
.