CSS image-resolution Property

The image-resolution property defines the intrinsic resolution of an image, determining how many image pixels are squeezed into a single CSS pixel.

img { image-resolution: [ from-image || <resolution> ] && snap; }
from-image Uses the intrinsic resolution of the image as specified in its own metadata.
<resolution> Specifies a specific resolution using units like dpi, dpcm, or dppx.
snap Rounds the resolution to the nearest value that allows image pixels to align with device pixels.

Code Examples

A basic example showing how to manually set an image to render at 300 dots per inch.

<style>
.print-quality {
  image-resolution: 300dpi;
  border: 4px solid #333333;
}
</style>
<img src="large-photo.jpg" class="print-quality" alt="High density photo">

An advanced example using JavaScript to toggle the resolution and snapping of an image dynamically.

<div id="ui-box">
  <img id="dynamicImg" src="asset.jpg" style="image-resolution: from-image; border: 2px solid #000000;" alt="Metadata Image">
  <button onclick="setDensity()">Override Density</button>
</div>

<script>
function setDensity() {
  const myImg = document.getElementById("dynamicImg");
  // Using JS to change the density for supported browsers
  myImg.style.imageResolution = "150dpi snap";
  myImg.style.borderColor = "#ff0000";
  console.log("Resolution updated to 150dpi with snapping.");
}
</script>

Pro Tip

If you are building something specific for an environment where you know Firefox is the only browser being used, you can use "snap" to eliminate the slight blurring that happens when images are scaled to non-integer sizes. For the rest of the web, treat this property as a historical curiosity and focus your energy on mastering responsive images via HTML attributes.

Deep Dive

Think of this property like packing a suitcase. You have a fixed amount of clothes (pixels), and the resolution determines how tightly you pack them into the bag (the display area). By default, browsers assume one image pixel equals one CSS pixel (1dppx). However, high-quality images often carry metadata telling the computer they were intended for high-density printing, like 300dpi. This property allows the browser to read that metadata using the "from-image" value or manually override it. If you set a higher resolution, the image appears smaller but sharper because the pixels are packed tighter. If you use the "snap" keyword, the browser rounds the math to ensure every image pixel lines up perfectly with the physical screen grid, preventing the blurriness caused by sub-pixel rendering.

Best Practices

The best practice is actually to avoid this property for production websites. Because it was never widely adopted by Chrome or Safari, it is effectively a dead feature. Instead, use the "srcset" and "sizes" attributes on your "img" tags or the "picture" element. These are the modern, standard ways to serve high-resolution images to devices that can handle them without breaking the layout in other browsers.

Common Pitfalls

The biggest trap developers fall into is assuming this works like a responsive image fix. It does not have support in Chromium-based browsers (Chrome, Edge) or WebKit (Safari). If you apply this property, it will simply be ignored by the majority of your users. Also, if you use "from-image" and the image file does not contain resolution metadata (EXIF data), the browser will just fall back to the default 1dppx.

Accessibility

Resolution itself doesn't affect screen readers, but it can affect visual accessibility. If you force a very high resolution on a low-resolution image, it might become too small for users with visual impairments to see clearly. Always ensure that the final rendered size of the image on the screen is large enough for its context, regardless of the pixel density.

Dev Data Table: image-resolution property

default from-image
animatable no
inherited yes
experimental yes
year_intro 2012
year_standard 0
js_syntax_1 element.style.imageResolution = "300dpi";
js_syntax_2 element.style.setProperty("image-resolution", "from-image");
js_note Since browser support is extremely limited, manipulating this property via JavaScript will likely have no visual effect in modern browsers.
browsers { "Chrome": 0, "Edge": 0, "Firefox": 26, "Safari": 0, "Opera": 0, "Chrome Android": 0, "Safari on iOS": 0, "Samsung Internet": 0, "Opera Mobile": 0 }
results render here...