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 results are horrible. The browser’s default scaling algorithm (usually bi-linear interpolation) has applied anti-aliasing to the image. While good for the majority of purposes, this type of scaling sacrifices the detail in our pixel art.
I ran into exactly this issue while building my recent feature on the classic 90s strategy game Command & Conquer. Thankfully, there’s now a way to tell the browser to use nearest-neighbour interpolation, as we used in Photoshop, to preserve image pixelation.
The CSS Image Rendering Property
The 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:
See the Pen by Tom Bennet (@tombennet) on CodePen.
Browser Support
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, while 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 gathered them into a Gist for convenience.
.pixelated {
-ms-interpolation-mode: nearest-neighbor; /* IE 7+ (non-standard) */
image-rendering: -webkit-crisp-edges; /* Safari 6 - 9 */
image-rendering: -moz-crisp-edges; /* Firefox 3.6 - 64 */
image-rendering: crisp-edges; /* Firefox 65+ */
image-rendering: pixelated; /* Chrome 41+, Edge 76+, Safari 10+ */
}
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.
I hope this short guide has been useful. Let me know your thoughts. You might also enjoy my feature on Command & Conquer, which prompted me to explore this technique.
Thanks for reading, and may all your pixel art stay gloriously blocky.