- ×
JavaScript and LESS helpers for rendering high-resolution image variants
Filed under miscellaneousretina.js
JavaScript, Sass, Less, and Stylus helpers for rendering high-resolution image variants
retina.js
makes it easy to serve high-resolution images to devices with displays that support them. You can prepare images for as many levels of pixel density as you want and letretina.js
dynamically serve the right image to the user.How it works
There are 4 ways to use
retina.js
:- Automatically swapping out
src
paths onimg
tags. - Automatically swapping out background image URLs in inline styles.
- Manually specifying the location of a high-res image variant (works for
src
attributes and inline styles). - Automatically creating media queries for CSS background images.
Img Tags
retina.js
assumes you are using Apple's prescribed high-resolution modifiers (@2x, @3x, etc) to denote high-res image variants on your server. It also assumes that if you have prepared a variant for a given high-res environment, that you have also prepared variants for each environment below it. For example, if you have prepared 3x variants,retina.js
will assume that you have also prepared 2x variants.With this in mind, you'll specify your highest environment level with the
data-rjs
attribute and letretina.js
take it from there.Let's say you have an image on your page that looks like this:
<img src="/images/my_image.png" data-rjs="3" />
In this case, we've set our resolution cap at "3", denoting that we've prepared 3x and 2x image variants. When the page loads,
retina.js
will check the actual resolution of the device environment to decide whether it should really serve up a 3x image. If the user happens to be in a 2x environment,retina.js
will serve up the 2x image instead, assuming it will find the image at/images/my_image@2x.png
.If the environment does have 3x capabilities,
retina.js
will serve up the 3x image. It will expect that url to be/images/my_image@3x.png
. If the environment has the ability to display images at higher densities than 3x,retina.js
will serve up the image of the highest resolution that you've provided, in this case 3x.Inline Styles
Previous versions of
retina.js
were unable to target background images set via inline styles. Now, if you apply adata-rjs
attribute to any kind of element other than animg
, the script will target inline background images instead ofsrc
attributes.So if you created an element like this:
<div style="background: url(/images/my_image.png)" data-rjs="3"></div>
retina.js
would convert it to something like this:<div style="background: url(/images/my_image@3x.png)" data-rjs="3"></div>
The logic behind image swapping is exactly the same when dealing with background images as it is when dealing with
src
attributes. If the user's environment only supports 2x variants,retina.js
will load the 2x variant instead of the 3x.Note that it is up to you in a case like this to correctly apply background sizing and any other necessary background-related styles to the element. retina.js will not affect these.
Manually Specifying a High-Res URL
In previous versions, you could tell the script where to find your high-res file by using the
data-at2x
attribute. Now, if you pass a URL to thedata-rjs
attribute,retina.js
will use the image at the path you specify for all high-resolution environments instead of trying to dynamically serve an auto-suffixed image path based on the environment's capabilities. This will work for bothsrc
attributes onimg
tags and inline background images on all other tags.For example, you might write something like this:
<img src="/images/my_image.png" data-rjs="/images/2x/my-image.png" /> <!-- or --> <div style="background: url(/images/my_image.png)" data-rjs="/images/2x/my-image.png"> </div>
If the user then loads the page in any kind of high-resolution environment, they'll get the following:
<img src="/images/2x/my-image.png" data-rjs="/images/2x/my-image.png" /> <!-- or --> <div style="background: url(/images/2x/my-image.png)" data-rjs="/images/2x/my-image.png"> </div>
Media Queries
retina.js
comes with mixins for SCSS, Sass, Less, and Stylus. These mixins work similarly to the JavaScript version in that they will dynamically serve images for as many high-res environments as you've prepared image variants for. Previously, these mixins were named "at2x" but because they now serve images for multiple environments, they have been renamed "retina".In each language, the retina mixin allows 4 parameters:
path
- The path to your standard resolution image.cap
- Optional. The highest resolution level for which you have prepared images. Defaults to 2.size
- Optional. A value to be applied to thebackground-size
property. Defaults toauto auto
.extras
- Optional. Any other values to be added to the background property. Defaults to nothing.
Here is an example wherein we are specifying that we have prepared images for both 2x and 3x environments:
SCSS
#item { @include retina('/images/my_image.png', 3, cover, center center no-repeat); }
Sass
#item +retina('/images/my_image.png', 3, cover, center center no-repeat)
Less
#item { .retina('/images/my_image.png', 3, cover, center center no-repeat); }
Stylus
#item retina('/images/my_image.png', 3, cover, center center no-repeat)
Regardless of the dialect, the output is effectively the same:
#item { background: url("/images/my_image.png") center center no-repeat; background-size: cover; } @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) { #item { background: url("/images/my_image@2x.png") center center no-repeat; background-size: cover; } } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { #item { background: url("/images/my_image@2x.png") center center no-repeat; background-size: cover; } } @media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) { #item { background: url("/images/my_image@3x.png") center center no-repeat; background-size: cover; } }
Compatibility
retina.js
is compatible with all modern browsers and should not throw errors in old browsers all the way back through IE6.Installing & Launching
JavaScript
There are 2 ways to use the JavaScript version of
retina.js
:- The old-school way (manually dropping the script into an html file).
- The new-school way (importing it into a larger JavaScript build process).
Old-School
To use retina.js the old-school way, download retina.min.js and put it on your server. Then, include the script in your html file at the bottom of your template, before your closing \
- Automatically swapping out