Situation Report

How To Create & Apply Retina Graphics To WordPress

Whether you’re a fan of it or not, Apple’s new retina devices have created a new set of opportunities for web-developers to make the internet an even more beautiful place. After spending a few months with an iPad with a retina display (3rd generation) and recently acquiring a MacBook Pro with a retina display, I decided to see how long it would take and how difficult it would be to prepare this site, built on WordPress, to display retina graphics. Turns out, it’s surprisingly easy.

Before diving in to actual tips, tricks, and code, it’s important to understand what the difference is between a standard display and a retina display.

Right now, I’m typing this on a MacBook Pro, 15″ retina display that is 2,880 pixels wide and 1,800 pixels tall, or a total of 5,184,000 pixels. Compare this to a standard 15″ MacBook Pro with 1,296,000 pixels, and you’ve got a retina display that has four pixels to every one single pixel on the standard display, providing the ability to display much crisper text, graphics, video, and animation. Because of this new ratio, we want all retina images on a web page to have four times the number of pixels as the standard image. Long story short, we’re going to take all images in our WordPress theme, posts, and pages, and make them twice as wide and twice as tall (or four times the original size).

To make life a little easier, I used a javascript library called retina.js, which you can find here. The library looks at all the images in their HTML format, generated by your WordPress, and tries to find the same image in the same location on your web server (or CDN, or whatever), but with the string “@2x” added just before the file extension.

For example, if your site’s logo was found at http://yoursite.com/images/logo.png, the retina.js library would automatically try and find http://yoursite.com/images/logo@2x.png, replace the standard image with that one, and set the size to the pixel height and width of the original image. However, this is only part of the equation – you need to provide the retina.js library with images that are four times the size of the standard. To do this, all images on the site need to have these high resolution duplicates created.

Creating Double Resolution Images
If your site assets are available as vector files (Adobe Illustrator, EPS files, etc.) you can simply scale them to twice the height and width, and then re-save for the web. Bitmaps are trickier. If you have Photoshop files that aren’t smart objects, you’ll need to recreate them at double resolution or they’ll look pixelated. That said, if you have smart objects and lines/vectors in your Photoshop layout, you can go into your Image Size settings and set Pixel Dimensions: Width and Height to 200 percent. (Check out bjango’s excellent article if you’d like to read more about Photoshop workflows when designing for retina displays.)

Most WordPress themes have post and page images along with some background images defined in CSS. We’ll treat these as three separate areas to update our images for retina compatibility in WordPress.

Theme Images in HTML
After creating all of your assets at double resolution, simply upload them to your theme’s images folder. That’s it. Your markup should stay exactly the same, so you’ll still have tags like

<img src="http://yoursite.com/images/logo.png" />

and the retina.js library will attempt to load images from your WordPress theme with the additional @2x string for retina displays.

Uploaded Images in Pages & Posts
Post and page images, whether inserted directly into the body or as a featured image, behave exactly the same way as theme images. The key difference is where you put them. Since post and page images are added to the wp-content/uploads/{year}/{month} folder pertaining to the date uploaded, you need to make sure that all retina images for WordPress posts and pages are put into the exact same folder as the original image otherwise the JavaScript library won’t find the image.

Theme Images in CSS
Properly loading retina images in WordPress via CSS is just slightly more complicated. For now, we’re essentially going to tell the CSS document to look for a cue that says “hey, I’m a retina display!”

Let’s just jump right into the code example – below you’ll find some of the CSS used for the logo on this site. The standard #logo rule simply outlines how to apply our background image. The media query below that translates to “If the pixel ratio is equal to or greater than 2, load this other background image instead, but display it in the same amount of relative pixels as the standard logo (thus providing the 4x retina quality).

#logo a {
	background: url(images/vuurr-logo.png) no-repeat center;
	width: 82px;
	height: 41px;
}

@media all and (-webkit-min-device-pixel-ratio: 2), all and (-moz-min-device-pixel-ratio: 1.5), all and (min-device-pixel-ratio: 2), all and (-o-min-device-pixel-ratio: 2/1) {
  #logo a {
    background-size: 82px 22px;
    background: url(images/vuurr-logo@2x.png) no-repeat center;
    width: 82px;
    height: 41px;
  }
}

The CSS above should take into account most modern browsers. However, since only Safari supports (and displays) the retina assets at the moment, we’re unable to verify 100% that the Mozilla, Opera, and standard extension will function properly, so your mileage may vary.

A note on the JavaScript
If you analyze the retina.js library, you’ll see that it’s relying on the window.devicePixelRatio JavaScript function. This is just fine, but unfortunately it seems that at the moment Firefox on the desktop fails to recognize it (though, interestingly, Firefox on Android seems to work just fine). The latest Chrome beta supports window.devicePixelRatio as well, but since at the moment the release versions of Chrome and Firefox do not support retina displays, we’re going to leave the retina.js library alone and wait for wider browser support of devicePixelRatio.

Wrapping it up
There isn’t a single formula that will always just work when prepping your WordPress site to support retina displays and images. Following some of the strategies in this guide should get you very close, though. When you have questions or are ready with comments and observations, please feel free to sound off our the comments section.

About Jonathan Kressaty

Partner and co-founder at Vuurr. Our clients know him as the brain behind all their development dreams.

Remarks

  1. Nice post, JK. Not sure what I expected but appreciate the clean, simple, usable info as well as the examples & links!

  2. How have you found page load time to increase with the increased size of images? I could see some issues loading image-heavy pages or pages with large images.

    • It’s a potential issue, but one that we believe isn’t a huge concern – odds are if you’re using a retina device you have some sort of high speed connection. Additionally, with proper compression of PNGs, even on image heavy pages you’re talking about what would most likely only amount to a couple hundred kb of additional bandwidth. We’ve toyed around with the idea of having a small bar load at the top of the page that asks if you’d like to load retina images, but since the process we’re using happens after the DOM is loaded, we don’t see it hindering normal usage even under low-bandwidth conditions.

  3. Hello, did you try the “WP Retina 2x” plugin? It creates all the images automatically for you, and it uses the same script (Retina.js). I’m the developer of the plugin so let me know what you think about it! Great theme by the way :)

    • Hey Jordy, I haven’t tried it, but how do you upscale the images? Without the original photo or vector document you’re just going to have the same effect. As I type this I realize it probably takes your uploaded media, and when it does the scaling creates the hi-res version if possible as well… right?

  4. I’m new to editing WordPress themes and coding in general. Where is the best place to put the retina.js script? I’ve read that you can place it in header.php, but I haven’t been able to get that to work for me. Any advice?

    • Hey Darron. If you open up header.php in your theme, you should be able to enter it just before the closing tag. If you have placed the retina.js file in a /js/ subfolder, it should look something like this:

      <script src=”<?php echo get_template_directory_uri(); ?>/js/retina.js”></script>

      The other option (the proper way of handling it) would be to use wp_enqueue_script() inside your functions.php file to load it. See my example here: https://gist.github.com/3381622

  5. Nice article, thanks! I’m thinking of going retina with my WP site, but I thought of something. I’m not hugely technical, but, at the rate of screen-resolution-progress (Apple’s iPhone has been surpassed by higher DPI screens now) would a simple 2x resolution cut it for the coming years? Or is there a chance that in a year or so where going x4? I dont have a device with a higher res then my iPhone 5 yet, but they exist… I’m wondering how Apple’s retina images look on those higher (going up to 440 DPI) devices…

    • Hey Paul
      Not sure if I’m (or any of us) at this point can speak to that with any great accuracy but I’m comfortable in this industry knowing it changes constantly. I don’t doubt at some point in the near future we’re looking at 4x or something similar but the reality of it now is we handle 2x on a lot of the new stuff we build that’s front-client-facing… but not all of it. It’s like responsive; not every site build needs it or can’t afford the extra planning and time in dev.
      I’d say yes we’re going there – but we’re not there yet and instead of waiting build what needs to be built for now.