Have you ever worked with retina graphics?
If so, when and what techniques did you use?TL;DR
“Retina” is an Apple marketing term commonly used for high-pixel-density displays. The practical concern is the device pixel ratio: one CSS pixel can be represented by multiple device pixels. Text, CSS shapes, and SVG usually scale cleanly; raster images and canvas content need enough source pixels without making every user download the largest asset.
Have you ever worked with retina graphics?
CSS pixels and device pixels
window.devicePixelRatio reports the ratio between CSS pixels and physical device pixels for the current display and zoom configuration. A ratio greater than 1 is common but is not guaranteed on every mobile device, and it can change when a window moves between displays.
A raster image displayed at 200 CSS pixels wide may need a 400-pixel-wide source to look sharp at a device pixel ratio of 2. Serving that larger source to every device wastes bandwidth, so the browser should be given candidates.
Images and icons
For an image with a fixed rendered size, density descriptors are concise:
<imgsrc="/images/logo.png"srcset="/images/logo.png 1x, /images/logo@2x.png 2x"width="200"height="60"alt="Acme" />
For fluid content images, width descriptors plus sizes are usually more appropriate because the browser can consider both the layout width and pixel density. SVG is often a good choice for logos, icons, and illustrations that can be represented as vectors, but photographs still need raster formats.
CSS background images can offer density candidates with image-set():
.brand-mark {background-image: image-set(url('/images/mark.png') 1x,url('/images/mark@2x.png') 2x);}
Canvas rendering
A canvas has separate CSS and bitmap dimensions. To avoid a blurry chart, size its backing store for the current ratio, then scale the drawing context:
const canvas = document.querySelector('canvas');const size = 240;const ratio = window.devicePixelRatio || 1;canvas.style.width = `${size}px`;canvas.style.height = `${size}px`;canvas.width = Math.round(size * ratio);canvas.height = Math.round(size * ratio);const context = canvas.getContext('2d');if (!context) {throw new Error('2D canvas is not available');}context.scale(ratio, ratio);
The implementation should also respond if the displayed size or pixel ratio changes. In practice, compare sharpness and transferred bytes in real target devices and browser DevTools rather than assuming the highest-resolution asset is always better.