Retina graphics for your website

retina.js is an open source script that makes it easy to serve
high-resolution images to devices that support them

  Download zip How it works  

How it works

There are now 4 ways to use retina.js:

  1. Automatically swapping out "src" paths on "img" tags.
  2. Automatically swapping out background image URLs in inline styles.
  3. Manually specifying the location of a high-res image variant.
  4. Automatically creating media queries for CSS background images.

In the most common case, you might have an image on your page that looks like this:
<img src="/images/my_image.png" data-rjs="3" />

By using the "data-rjs" attribute, you're telling retina.js that this image would like to opt in. Any images that don't use this attribute will be left alone.

By giving the "data-rjs" attribute a value of "3", you're telling retina.js that you have created high-res image variants for all environments up through 3 times traditional pixel density (meaning both 2x images and 3x images).

When a page loads, the script will check the user's environment to see what its display capabilities are. If its resolution is greater than all of your variants, your highest resolution variant will be served. If not, the script will serve up your matching variant. It does this by swapping out the value in your "src" attribute for something like...

Notice that the script assumes you use Apple's prescribed high-resolution modifiers (@2x, @3x, etc) to denote high-resolution image variants on your server.

If you don't use Apple's prescribed modifiers, you can use the "data-rjs" attribute to tell retina.js exactly where your high-res image lives.
<img src="/images/my_image.png" data-rjs="/images/2x/my_image.png" />

In this case, the script won't try to dynamically serve up variants based on the user's environment. It will simply serve the high-res variant you pass in whenever the environment is higher than traditional resoluion.

You can also use retina.js with background images set through inline styling. For example:
<div style="background: url(my_image.png);" data-rjs="3" />

Which will be converted to:
<div style="background: url(my_image@3x.png);" data-rjs="3" />

This will work for any HTML element besides the "img" tag. If it's an "img", retina.js will try to swap out the "src" attribute. If it's anything else, the script will go after inline background images. Everything else works exactly the same.

retina.js also comes with SCSS, Sass, Less, and Stylus helpers!

We'll get to these in a moment.

How to use

JavaScript (the modern way)

retina.js now works with pretty much any JavaScript build process you can imagine. The source code is written ES6 and is available via NPM and Bower as a package called "retinajs". Feel free to require or import it at your leisure.

When using retina.js this way, the script assumes you may not want it to run automatically. So in order to call it, you'll need to do something like the following:

import retina from 'retinajs';

window.on('load', retina);

JavaScript (the old-fashioned way)

The JavaScript helper script automatically replaces images on your page with high-resolution variants (if they exist). It also creates a global function called retinajs so that you can re-initialize the script whenever you want. To use it, download the minified script and include it at the bottom of your page.

  1. Place the retina.min.js file on your server
  2. Include the script on your page

    <script type="text/javascript" src="/scripts/retina.min.js"></script>

    (put it at the bottom of your template, before your closing </body> tag)
  3. That's it!

Manually calling the function

If you drop the script into your html file, you'll automatically get a function called retinajs attached to the global scope. If you're importing the script as part of a build process, you get the same function but you can name it whatever you want. So let's call it retinajs for now.

If you call retinajs() without any arguments, it'll attempt to process all the elements on the page that it hasn't already processed before. But you also have the option of passing it a collection, in which case it'll only try to process the elements in the collection, again, only if it hasn't processed those images before.

// Attempts to process all participating elements that
// haven't been processed before.

retinajs( [img, img, img] );
retinajs( $('img') );
retinajs( document.querySelectorAll('img') );
// Attempts to process only the elements in the collection.
// Each one still needs to be marked with `data-rjs` and
// will still be ignored if it has already been processed.

SCSS, Sass, LESS, and Stylus

The CSS preprocessor mixins are helpers for applying high-resolution background images in your stylesheet. For each dialect, you have the same 4 arguments:

  1. path - The path to your standard resolution image.
  2. cap - The highest resolution level for which you have prepared images. Defaults to 2.
  3. size - A value to be applied to the background-size property. Defaults to auto auto.
  4. extras - Any other values to be added to the background property. Defaults to nothing.

The mixin creates media queries specifically for high-resolution displays by changing the background image for the selector elements to use high-resolution (@2x, @3x, etc) variants and applying a background-size of the original image in order to maintain proper dimensions. To use it, download your favorite mixin, then import or include it in your SCSS/Less/etc stylesheet, and apply it to elements of your choice.

Example in SCSS:

@include retina('/images/my_image.png', 3, 100px 50px, center center no-repeat);


  1. Add the retina mixin to your stylesheet.
  2. In your stylesheet, call the retina mixin anywhere instead of using background-image

    #logo {
      @include retina('my_image.png', 3, 100px 50px, center center no-repeat);

      +retina('my_image.png', 3, 100px 50px, center center no-repeat)

    #logo {
      .retina('my_image.png', 3, 100px 50px, center center no-repeat);

      retina('my_image.png', 3, 100px 50px, center center no-repeat)

    Will compile to:

    #logo {
      background: url("my_image.png") center center no-repeat;
      background-size: 100px 50px;
    @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("my_image@2x.png") center center no-repeat;
        background-size: 100px 50px;
    @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
      #item {
        background: url("my_image@2x.png") center center no-repeat;
        background-size: 100px 50px;
    @media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) {
      #item {
        background: url("my_image@3x.png") center center no-repeat;
        background-size: 100px 50px;


Download zip Download source


We'd love your help. Fork us so we can make retina graphics easier for everyone.  

Made with love in Boulder, CO by Axial

Thanks to Zach Dischner for the kickass background photo. Check out his work on Flickr.