Until now, web developers have had very little control over how browsers render images when they’re scaled.
Take Mario, for instance:
This is a 24x32 pixel image, scaled up using Photoshop to preserve its crisp, blocky composition. It’s a great example of the low-res pixel art that’s long been a staple of retro and indie games. Let’s see how our image is rendered in the browser when scaled up using CSS:
As you can see, the effect is suboptimal - the browser’s default scaling algorithm (usually bi-linear interpolation) has applied anti-aliasing to the image. Whilst good for the majority of purposes, this type of scaling sacrifices the detail in our pixel art. Is there a way to tell the browser to use nearest neighbour interpolation, as we used in Photoshop, to preserve the pixelation of our Mario?
The CSS Image Rendering Property
image-rendering CSS property aims to do just this. The property can be applied to CSS background images, inline images, and canvas elements.
You can see the effect in the CodePen below. On the left, the image is rendered as per default behaviour, with the property value set to
auto. On the right, we’ve applied our preferred scaling method:
As with all cutting-edge features, there is a degree of inconsistency between browsers. Firefox supports the
crisp-edges value with the
-moz prefix, in both desktop and mobile versions. Safari now supports the same value, but with the
-webkit prefix, on both desktop and mobile. Opera, which is of course Chromium-based, supports the unprefixed value
pixelated, much like the most recent version of Google Chrome.
Finally, whilst Internet Explorer does not support
image-rendering, we can achieve the same effect by using a non-standard property that has been knocking around since IE 7. By applying
-ms-interpolation-mode: nearest-neighbor to the image, our pixel art will remain pleasingly blocky.
The appropriate combination of properties and prefixes are provided below, including some non-standard legacy values supported in older browsers. I’ve also put them into a SCSS mixin for convenience, which is available here as a gist.
If the current browser support is a serious obstacle for you, there are workarounds and alternatives: you can manually resize and export at a higher resolution using your preferred graphics program, or you can upscale using canvas with the
imageSmoothingEnabled property. But that’s a tutorial for another time.
Thanks for reading, and may all your pixel art stay gloriously blocky.