Window.devicePixelRatio

WindowプロパティのdevicePixelRatioは現在のディスプレイにおけるCSS解像度と物理解像度の比を返します。 これは物理1ピクセルの大きさに対するCSS1ピクセルの大きさの比率と考えることもできます。もっと簡単に言うと、CSS上の1pxが物理ピクセルいくつで表示されているかという値です。

これは一般的なディスプレイと、HiDPI(高DPI)やRetinaのように同じ大きさのオブジェクトを描画するのにより多くのピクセルを使って鮮明さを得ているディスプレイとの差異を扱うのに便利です。

この値が変更(ユーザが異なるピクセル密度のディスプレイにウィンドウをドラッグしたときなどに発生します)されたときに通知を受ける方法はありません。そうしたイベントやコールバックが存在しないためです。唯一の方法は devicePixelRatio の値を定期的にチェックすることですが、あまりにも頻繁すぎるチェックはパフォーマンスに影響するので気を付けましょう。

構文

value = window.devicePixelRatio;

倍精度浮動小数点の値であり、CSS ピクセル解像度に対するディスプレイの物理的なピクセル解像度の比率を表します。この値が 1 であることは、それが伝統的な 96 DPI (プラットフォームによっては 76 DPI) であることを意味し、2 であることは、HiDPI やレティナのディスプレイであると考えられます。それ以外の値が返されることもあり、それは一般的でない低解像度のディスプレイの場合や、より考えられるのはスクリーンが標準的な 96 または 76 DPI の解像度の単純な 2 倍よりも高いピクセル密度を持つ場合です。

使用例

例 1: <canvas> の解像度を補正する

レティナでは canvas がぼやけて見えることがあるでしょう。window.devicePixelRatioを使うことで、鮮明に表示するために必要なピクセル密度を調べます。

HTML

<canvas id="canvas"></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

// 表示サイズを設定(CSSにおけるピクセル数です)。
var size = 200;
canvas.style.width = size + "px";
canvas.style.height = size + "px";

// メモリ上における実際のサイズを設定(ピクセル密度の分だけ倍増させます)。
var scale = window.devicePixelRatio; // レティナでこの値を1にするとぼやけたcanvasになります
canvas.width = size * scale;
canvas.height = size * scale;

// CSS上のピクセル数を前提としているシステムに合わせます。
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';

var x = size / 2;
var y = size / 2;

var textString = "I love MDN";
ctx.fillText(textString, x, y);

この画像は、レティナディスプレイにおける異なる値の影響を表すものです。

例 2: 画面解像度やズームレベルの変化を監視する

この例では、devicePixelRatio の値をチェックして必要な変化に対処できるよう、メディアクエリを設定してデバイス解像度がいつ変化するかを監視します。

JavaScript

この JavaScript のコードは、デバイス解像度を監視するメディアクエリを作り、devicePixelRatio の値が変化したときはいつでもそれをチェックします。

let pixelRatioBox = document.querySelector(".pixel-ratio");
let mqString = `(resolution: ${window.devicePixelRatio}dppx)`;

const updatePixelRatio = () => {
  let pr = window.devicePixelRatio;
  let prString = (pr * 100).toFixed(0);
  pixelRatioBox.innerText = `${prString}% (${pr.toFixed(2)})`;
}

updatePixelRatio();

matchMedia(mqString).addEventListener("change", updatePixelRatio);

文字列 mqString は、メディアクエリそのものになるように作ります。このメディアクエリは、(resolution: 1dppx) (標準的なディスプレイの場合)、または (resolution: 2dppx) (HiDPI / レティナディスプレイの場合) のような内容で始まり、現在のディスプレイ解像度のピクセルあたりのドット数が特定の数であるかをチェックします。

関数 updatePixelRatio() は、現在の devicePixelRatio の値を取得し、pixelRatioBox 要素の innerText に、その比率を百分率と小数第 2 位までの未加工の 10 進数の値の両方で表示する文字列を設定します。

そして、関数 updatePixelRatio() が最初の値を表示するために一回実行され、その後メディアクエリが作られて updatePixelRatio()change イベントのハンドラーとして登録するために addEventListener() が実行されます。

HTML

この HTML は、説明文を含むボックスと、現在のピクセル比率情報を表示する pixel-ratio ボックスを作成します。

<div class="container">
  <div class="inner-container">
    <p>この使用例により、ページをズームまたはズームアウトすること
       (または異なる表示倍率の画面にページを移動させること) の
       <code>Window.devicePixelRatio</code> プロパティに与える影響がわかります。
       どのようなことが起こるか、試してみましょう!</p>
  </div>
    <div class="pixel-ratio"></div>
</div>

CSS

body {
  font: 22px arial, sans-serif;
}

.container {
  top: 2em;
  width: 22em;
  height: 14em;
  border: 2px solid #22d;
  margin: 0 auto;
  padding: 0;
  background-color: #a9f;
}

.inner-container {
  padding: 1em 2em;
  text-align: justify;
  text-justify: auto;
}

.pixel-ratio {
  position: relative;
  margin: auto;
  height: 1.2em;
  text-align: right;
  bottom: 0;
  right: 1em;
  font-weight: bold;
}

結果

仕様

仕様 状況 コメント
CSS Object Model (CSSOM) View Module
Window.devicePixelRatio の定義
草案 初期定義

ブラウザ実装状況

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
devicePixelRatioChrome 完全対応 ありEdge 完全対応 12Firefox 完全対応 49IE 完全対応 11Opera 完全対応 41Safari 完全対応 9.1WebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 ありOpera Android 完全対応 ありSafari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり

凡例

完全対応  
完全対応

関連情報