A Basic Guide to Pixel Perfection on the Web

Responsive web design has become a crucial part of most company websites.  For smartphones: Increasing the font size of text, making links easier to press for fingers and rearranging the layout to work on a small, vertical display is ideal. But aside from those points, there’s one other thing that can improve your website on higher resolution devices.

Phones, tablets, and computer screens are squeezing more and more pixels into smaller spaces. For example, the 27″ 5K iMac has a PPI (Pixels Per Inch) of 218, compare that to a 21″ screen with a resolution of 1920×1080 which has a PPI of 100.13. That’s more than twice the amount of pixels in the same amount of space.

As you can see in the image below: some displays can have 4 pixels squeezed into the same space as 1 on another device (2 vertical and 2 horizontal). Some devices may even fit more than that.

Retina Pixels

What this means visually is that websites that use PNG or JPG images will be twice as small on a Retina (2x) display because there’s twice as many pixels in the same amount of space. To make the image appear to be the same size as a non-Retina display would mean stretching the image – resulting in blurriness.

Example of a non-Retina image becoming blurry on a Retina display

There are a few solutions to this.

SVG Images

For relatively simple icons that are made in vector software, such as Adobe Illustrator or Sketch, it’s beneficial to use SVG images. SVG images are vector-based rather than raster so they scale well at all sizes. Vector images use code to draw rather than setting each pixel independently, so they can be scaled to different sizes easily.

svg-examplesvg-examplesvg-example

Above is an example of an SVG image. It is the exact same file set at three different widths: 50px, 100px, and 200px. IE8 and older versions of Android do not support SVG images, so bear that in mind when using them. If a significant amount of your website’s userbase use these then you might want to avoid utilising them.

Media Queries

For photos and more complex images, it’s best to use CSS media queries or source sets to show seperate images for varying display sizes.

Due to the vast amount of different PPIs for devices, I recommend displaying better images for 144dpi and higher. With CSS this can be achieved like so:

.photo {
  background-image:url('photo.png');
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi){
  .photo {
    background-image:url('photo@2x.png');
  }
}

The above code means that devices with a PPI of 144 or more, and a device pixel ratio higher than 1.5, will show an image that’s twice the pixel dimensions of the original image. This allows for images on these higher PPI devices to look significantly crisper.

The device pixel ratio is the amount of “real” pixels that are used to display 1 “virtual” pixel. For instance, the iPhone 7 has a device pixel ratio of 2. Which means that 2 real pixels on the iPhone fit into 1 virtual pixel displayed by the CSS. In this instance, having a retina image that’s twice the size of the regular image would fit onto the iPhone’s screen and look about the same size as a device with a device pixel ratio of 1 displaying the regular image.

You may even want to target devices with a pixel ratio of 3 such as the Samsung Galaxy S4.

@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 200dpi){
  .icon {
    background-image:url('icon@3x.png');
  }
}

There are a lot of varying pixel ratios, especially in the Android ecosystem, to the point where it is impractical to create separate images for all of them. I recommend sticking to 1x, 2x, and possibly 3x depending on your use-case.

Source sets

For images that need to display in an img tag rather than as a background image, it’s possible to use the source set attribute to specify different sizes.

<img src="example.jpg" srcset="example.jpg 1x, example@2x.jpg 2x" alt="Example Sourceset Image Code" />

There are two downsides to this approach. Retina displays will end up downloading two images, the original image source, and the larger image. The other downside is that not all browsers support it. In fairness, the majority of modern browsers do – with the exceptions of IE11 and Opera mini.

SASS Snippet

Here at The Studio, our development team use SASS for our stylesheets. There’s a handy SASS mixin that makes it easy to add retina background images to your CSS.

@mixin image-2x($image, $width, $height) {
  @media (min--moz-device-pixel-ratio: 1.3),
         (-o-min-device-pixel-ratio: 2.6/2),
         (-webkit-min-device-pixel-ratio: 1.3),
         (min-device-pixel-ratio: 1.3),
         (min-resolution: 1.3dppx) {
    /* on retina, use image that's scaled by 2 */
    background-image: url($image);
    background-size: $width $height;
  }
}
div.logo {
   background: url("logo.png") no-repeat;
   @include image-2x("logo2x.png", 100px, 25px);
 }

Source: https://web-design-weekly.com/2013/05/12/handy-sass-mixins/

To learn more about pixel density, check out this blog post by Peter Nowell, Pixel Density, Demystified which goes into greater detail.

If you’re interested in having a website developed, check out our range of web development services or contact us for a quote here.

IMPORTANT NOTICE: Any orders accepted by us will be subject to our standard terms and conditions a copy of which can be accessed [here]. No other terms and conditions will be accepted by us, unless agreed to in writing