Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Instant Website Optimization for Retina Displays How-to

You're reading from   Instant Website Optimization for Retina Displays How-to Learning simple techniques which will make your website look stunning on high-definition Retina Displays

Arrow left icon
Product type Paperback
Published in Jan 2013
Publisher Packt
ISBN-13 9781849695121
Length 56 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Kyle Larson Kyle Larson
Author Profile Icon Kyle Larson
Kyle Larson
Arrow right icon
View More author details
Toc

Pixel ratio detection with JavaScript (Become an expert)


There are a number of good options for implementing Retina images with CSS and vector images, but there isn't a simple solution available for the standard <img> tag. Photographs and other images are typically added using HTML within the content of websites. Until we have a new HTML tag available or an update to the existing <img> tag to reference high-resolution images, we'll have to find an alternative solution.

Currently, the best two options available are using either a front-end or server-side scripting solution. This recipe will discuss how to use JavaScript to replace your normal images with high-resolution images if a Retina Display is detected.

Getting ready

To get started, we'll need a photo to use for our test page. If you've been following along with the previous recipes you can reuse your myImage.jpg photograph, or if not, any large photograph will work. I'll be using my original photo, which is 1400 x 800 pixels.

How to do it...

  1. If you don't already have your photos saved from before, save your image as myImage@2x.jpg inside your /images/ folder within the /retina/ folder. Then resize the image to 50 percent and save it as myImage.jpg in the same folder.

  2. Create an HTML document called javascript.html inside the /retina/ folder. Inside the <head> tag of the basic HTML structure, we'll start by including jQuery.

    <head>
    
      <script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
    
    </head>
  3. Next we'll add some HTML code to the <body> tag to display two versions of our photo.

    <body>
    
      <img src="images/myImage.jpg" width="700" height="400" />
    	
      <img src="images/myImage.jpg" class="retina" width="700" height="400" />
  4. Then we'll add some JavaScript to swap out the high-definition image.

    <script type="text/javascript">
      $(function () {
    		
        if (window.devicePixelRatio >= 2) {
              
          var images = $("img.retina"),
          imageType,
          imageName;
              
              // loop through the images and make them hi-res
            for(var i = 0; i < images.length; i++) {
                            
                // create new image name
              imageType = images[i].src.substr(-4);
              imageName = images[i].src.substr(0, images[i].src.length - 4);
              imageName += "@2x" + imageType;
              	
                //rename image
              images[i].src = imageName;
                
              }
         }
    	
        });
      </script>
    </body>
  5. If you are working on a Retina device you should be able to open this page locally; if not, upload the folder to your web server and open the page on your device. You will notice how much sharper the second image is than the first image. On a device without a Retina Display, both images will look the same.

How it works...

To get started, we included the jQuery library to make it easy to select all the image elements on the page that we want to replace with high-resolution versions. This example is only replacing a single image, but the code can be applied to any images you add to your page.

Next, we added two HTML <img> tags. Make sure to specify the width and height of the images so when we replace the image with the Retina version the size remains the same. In the second <img> tag we included class="retina" because our JavaScript will use this class to determine which images to replace with a high-resolution version.

Then we created a JavaScript function to load our Retina images. Our script started with an if statement to check if the window.devicePixelRatio is equal to or greater than two, so we only run the script if the user is on a Retina device.

If a Retina device is being used, then we create three variables. The first variable, called images, is set to contain all the images with the retina class. Then we created two additional variables, imageType and imageName, to store the image's extension (for example, .jpg) and the filename without the extension.

The next section of code is a for loop, which continues to run until all the images with the retina class (that were stored in our images variable) have been updated. The first line of the loop sets imageType to the image's extension, which are the final four characters of the filename. Then it sets imageName to the initial part of the filename, without the extension. Now that we have the image name split into two variables, we're ready to add in our Retina image.

The next line of the loop adds @2x to the imageName property and then completes the filename by adding the extension. For this code to work, you'll need to name all your high-resolution images the same as your normal images, but add @2x at the end of the name like we've done here. Finally the src value of the <img> tag is set to our new high-resolution filename.

There's more...

When using this script you'll need to make sure to only add class="retina" to the images that you have supplied a high-resolution image for. If you add it to an image without a corresponding @2x image you'll have a broken <img> tag. You could also use this script without that class to simplify it, but you would have to be very careful to ensure that you have two versions of every image on your site.

There are a couple of downsides to this JavaScript based Retina image implementation. First, if the user has JavaScript disabled they will only see the regular images. Second, Retina browsers may begin to download the small images first before they are replaced, which may use extra bandwidth. This wouldn't be much of a concern on a small page with few images, but it could cause issues on larger sites.

Loading only the correct image

Making some changes to our code could solve the image loading issue (starting to load the small image before it has been replaced). Instead of setting src in our <img> tag, we could use data-src so the browser doesn't see the image location. Then in our JavaScript we would create a variable with the data-src attribute, set it to the image's src if the device is non-Retina, or add @2x and set that to src on a Retina device.

To make this work for browsers with JavaScript disabled, we'd also want to add our normal image tag wrapped inside of a <noscript> tag. You can download an implementation of this script called retinise from dahliacreative.com/retinisejs or try out Adam Bradley's foresight.js at https://github.com/adamdbradley/foresight.js. Adam's script also includes additional features, such as network connection testing to see if the user has a fast enough connection before loading the larger images.

Targeting other high-density devices

This script uses window.devicePixelRatio >= 2 to detect Retina devices. All of Apple's Retina Displays have a pixel-ratio of 2, which this code corresponds to, however other manufacturers may make displays with pixel-ratios below this value. If you'd like to target those devices as well, you could lower this value. For example, window.devicePixelRatio >= 1.5. This will depend on if you feel that it is worth serving the larger files to these devices, or you could create another if statement and corresponding images to target these devices specifically.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image