The spec changed in Feb 2021.
crisp-edges
now means "use nearest neighbor" and pixelated
means "keep it looking pixelated" which can be translated as "if you want to then do something better than nearest neighbor that keeps the image pixelated".
The current reality (2022) is, crisp-edges
(only implemented in Firefox) and pixelated
(implemented in Chrome/Edge and Safari) are actually implemented as nearest neighbor filtering.
But a functional note: if you have an image you're trying to scale up using image-rendering: crisp-edges
your users may not be getting the result you expect. The problem is, CSS works in CSS pixels. CSS pixels are translated to device pixels. The translation from CSS pixels to device pixels is called the devicePixelRatio
. The devicePixelRatio
can be a non integer value.
So, for example, you have 128x128 pixel image that you want scaled to 256x256 with image-rendering: pixelated
like this
<img src="128x128.png" style="width: 256px; height: 256px; image-rendering: pixelated">
and you think the user will see each pixel of the original image scaled to 2x2.
But, the user's devicePixelRatio might not be an integer. My desktop's devicePixelRatio is 1.25 which means asking for a style of width: 256px; height: 256px;
ends up making a 320x320 device rectangle. The 128x128.png will be scaled to 320x320 which, with image-rendering: pixelated
, when implemented as nearest-neighbor
means some pixels are going to get scaled to 2x2 and others 1x1.
You can see an example here. Here's a 64x64.png
And here's 4 ways of scaling it 2x to 128x128
- the default (image-rendering: smooth)
- image-rendering: pixelated
- image-rendering: crisp-edges
- offline scaling to 256x256 then scaled back to 128x128 using the default (image-rendering: smooth)
.inline {
display: inline-block;
border: 1px solid red;
text-align: center;
padding: 10px;
}
<div class="inline">
<img src="https://i.sstatic.net/akzX9.png"
style="width: 128px; height: 128px;">
<div>smooth up</div>
</div>
<div class="inline">
<img src="https://i.sstatic.net/akzX9.png"
style="width: 128px; height: 128px; image-rendering: pixelated">
<div>pixelated up</div>
</div>
<div class="inline">
<img src="https://i.sstatic.net/akzX9.png"
style="width: 128px; height: 128px; image-rendering: crisp-edges">
<div>crisp up</div>
</div>
<div class="inline">
<img src="https://i.imgur.com/aahR6GT.png"
style="width: 128px; height: 128px;">
<div>smooth down</div>
</div>
<p>zoom in/out with Ctrl/Cmd +/-</p>
If you run the snippet and then zoom in your browser (Ctrl/Cmd +/-), at least on my machines the first 2 look much worse than the last one.
Also here's a library to scale in JavaScript which makes image-rendering: pixelated/crisp-edges
more useful by making sure the image is always scaled to a multiple of device pixels.
pixelated
isnt supported at all at present? – Frankfrankalmoignimage-rendering
. Is it even supported yet? – Jowettpixelated
isn't supported in any browser yet. I'm just interested in what these properties are proposed to do. – Genital