The Retina.js script is one of those scripts that makes things so much easier that sometimes you wonder why responsive images are so difficult.
If you don't feel ready to deal with the <picture> and/or srcset and sizes attributes, I don't blame you. It's scary but I recommend that you keep trying to understand these tools since that's the state of the art of responsive images.
The Retina.js script was developed by the folks at Imulus (http://imulus.com/). The Retina.js script isn't a JavaScript-only solution; they also have a Sass mixin that produces the same results without the dependency on JavaScript.
Let's take a look at the JavaScript solution first.
Using the script couldn't be any simpler. We need to download the script from https://github.com/imulus/retinajs/blob/master/dist/retina.min.js
Then, we place the script at the bottom of the HTML, right before the closing <body> tag:
<!DOCTYPE html>
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="no-js ie9" lang="en"> <![endif]-->
<!--[if gt IE 9]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Retina.js - JavaScript Solution</title>
</head>
<body>
...
<script src="js/retina.min.js"></script>
</body>
</html>Then, we add an image to our markup:
<!DOCTYPE html>
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="no-js ie9" lang="en"> <![endif]-->
<!--[if gt IE 9]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Retina.js - JavaScript Solution</title>
</head>
<body>
<img src="images/grandmasters-default.jpg" alt="">
<script src="js/retina.min.js"></script>
</body>
</html>That's it! We don't have to do anything to the markup, unless we want to exclude an image from being replaced. I explain how to do this coming up next.
The basic function of the JavaScript solution of Retina.js is that it looks for images in the page and replaces them with high-resolution versions if they exist on the server.
You need to name your high-resolution images with the @2x modifier right at the end of the name.
In other words, if you have the following image:
<img src="images/grandmasters-default.jpg" alt="">
Retina.js replaces it with the following one:
<img src="images/grandmasters-default@2x.jpg" alt="">As long as the @2x image exists on the server, Retina.js replaces it. If the image doesn't exist, then it won't replace it.
Well, this is weird—a JavaScript solution that somehow also happens to have a CSS solution? Sweet! Note that this Sass mixin is for applying background high-resolution images.
The Sass mixin looks like this:
@mixin at2x($path, $ext: "jpg", $w: auto, $h: auto) {
$at1x_path: "#{$path}.#{$ext}";
$at2x_path: "#{$path}@2x.#{$ext}";
background-image: url("#{$at1x_path}");
@media all and (-webkit-min-device-pixel-ratio : 1.5),
all and (-o-min-device-pixel-ratio: 3/2),
all and (min--moz-device-pixel-ratio: 1.5),
all and (min-device-pixel-ratio: 1.5) {
background-image: url("#{$at2x_path}");
background-size: $w $h;
}
}The usage is quite simple:
.hero {
width: 100%;
height: 510px;
@include at2x('../images/grandmasters-default', jpg, 100%, auto);
}We need to declare the file extension, the width, and the height as comma-separated values. The preceding Sass snippet will compile to this:
.hero {
width: 100%;
height: 510px;
background-image: url("../images/grandmasters-default.jpg");
}
@media all and (-webkit-min-device-pixel-ratio: 1.5), all and (-o-min-device-pixel-ratio: 3 / 2), all and (min--moz-device-pixel-ratio: 1.5), all and (min-device-pixel-ratio: 1.5) {
.hero {
background-image: url("../images/grandmasters-default@2x.jpg");
background-size: 100% auto;
}
}Here's a demo I created for this in CodePen: http://codepen.io/ricardozea/pen/c3af015b325da6ee56cf59e660f3cc03