IE11: Force sharp SVG background image scaling using CSS

Demonstrating a quick CSS fix for blurry SVG background images in Internet Explorer 11.

Screenshot of SVG rendered poorly by Internet Explorer 11
Figure 1: Blurry SVG before applying background scaling solution.
Screenshot of SVG rendered sharply by Internet Explorer 11
Figure 2: Sharp SVG rendering with CSS scaling solution applied.

The problem

SVG rendering doesn’t always work as expected. To output a vector graphic as pixels on a display, browsers need to rasterize the image, sometimes not resulting in the level of quality you would expect from a graphics standard like SVG, which theoretically supports scaling to arbitrary sizes.

IE11 sometimes produces blurry output when using scaled SVGs as CSS background images. This is readily apparent with SVG icons that should have sharp edges.

What works

It is possible to scale a background image SVG using background-size: 100% or background-size: cover. This works perfectly well as long as the background image’s containing element has an integer height and width.

What doesn’t work

I’ve narrowed it down to this: IE11 blurs SVG background images when they are scaled to a size with a computed height or width that is not an integer value in pixels. The problem isn’t about the SVG’s intrinsic size, but the size the SVG is being scaled to. When that target size is fractional, we get a blurry image rendered, despite SVG being a vector format.

Because many layouts use rem units, needing to handle computed pixel values that aren’t whole numbers is a fairly common occurrence. There is an easy workaround: size the background image manually so that it renders to a clean, whole number value that IE can handle. There’s also another more general solution.

The solution

The simplest solution I’ve implemented to solve this blurry SVG issue is convincing the browser to rasterize the SVG at a larger size, then scale down the output using a CSS transform. After transforming the element, use a negative margin to make it fill the same space as before. This is needed because CSS transforms don’t affect an element’s impact on its surroundings.

The result is a SVG at exactly the size you want and free from IE11’s SVG rendering fuzziness. Although it’s not ideal to upscale the image rendering and then downscale the output on the page, it's not an issue for typical use cases I’ve encountered.

I’ve put together a CodePen demonstration of the CSS required for this solution:

See the Pen eNaVQm by C Tidd (@ctidd) on CodePen.