Skip to content

Allows you to specify two images in a responsive_image_tag, and includes a javascript generator which will rewrite the DOM, requesting the correct image based on the screen size of the current client device.

License

futurechimp/responsive_image_tag

Repository files navigation

responsive_image_tag

Creating responsive images

It’s quite common today for web sites to be viewed on a wide range of devices, from powerful desktop workstations with huge screen resolutions and plenty of bandwidth, to tiny resource-constrained mobile devices. Serving images to this wide range of clients becomes an issue: if you make your images large, you’ll severely degrade performance on mobile phones, but if you make your images small, they’ll look terrible to desktop users.

Wouldn’t it be nice if you could serve small images to mobile clients, and large images to desktop clients? The HTML spec doesn’t really allow for device-specific asset serving, but it can be done with a little dash of cleverness. The technique used here allows you to serve device-specific images, and not make two server requests (saving bandwidth and server load).

We’ve packaged it up as a rubygem.

responsive_image_tag is a Rails helper which selects an image depending on the width of the current device. The screen.width is detected by javascript and then an image element is inserted in the page with a dynamically created src attribute.

It works with Rails 2, Rails 3, and Padrino. There is a jQuery plugin which handles the image replace functionality.

Motivation and approach

You can find out what problems we’re trying to solve with this code by reading the blog post about it here.

Although this is packaged as a ruby gem, the approach is generally valid across platforms, and as a bonus, it is accessible - screenreaders and web crawlers will see the content of the <noscript> tag, and parse the content quite happily.

HTML structure

Here’s the HTML which the helper inserts into the page:

<span class="img-placeholder"></span>
<noscript data-fullsrc="big.jpg" data-mobilesrc="small.jpg" class="responsivize" data-alttext="Alt text" data-cssclass="css-class">
  <img alt="Image reads deliver for today, inspire for tomorrow" class="scale-with-grid" src="big.jpg" />
</noscript>

The responsive images have to appear for non-javascript users as well as those with javascript turned on.

To achieve this the helper places the default image inside a <noscript> tag which is then deleted by the javascript library. The image attributes such as full size, mobile size and alt text are also stored as HTML5 data attributes on the <noscript> tag so they are available in the DOM for the javascript to access.

The library relies on a trick which has all the elegance of a greasy late-night kebab: child elements of the <noscript> tag are not added to the DOM, so deleting the <noscript> prevents an HTTP request being made to the server. This way only the image being requested by the dynamically inserted image tag is making a request.

To insert the dynamically created image element into the page you need a parent element in the DOM to append to. The rails helper also creates a <span> tag with a class of “img-placeholder” to house the new image.

When the DOM is ready the javascript object responsiveImageTag detects all <noscript> elements on the page with a class of “responsivize”.

It retrieves the HTML5 data attributes (data-mobilesrc, data-fullsrc, data-alttext and data-cssclass) and then creates an image tag with the correct source depending on the available screen width of the users device. Any device smaller than 768px is considered to be a mobile device. The library inserts the new element into the page and the <noscript> tags are then hidden from view.

Installation

Put it in your Gemfile:

gem 'responsive_image_tag'

If you’re using Padrino, you’ll need to put the gem 'responsive_image_tag' requirement in your Gemfile after gem 'padrino' as it depends on Padrino being loaded so it can attach itself to the Padrino generators.

Then install it:

bundle install

There’s a generator which copies the JavaScript file into place. For Rails this will be public/javascripts but in Padrino you can specify an alternative location.

Rails 3

rails g responsive_image_tag:copy_js

Rails 2

script/generate responsive_image_tag *Currently untested in 0.3.X

Padrino

padrino g copy_rit_js

Options:

-d, [–js_destination] The destination path to copy the Javascript file too. Default: ‘public/javascripts’

jQuery plugin

You could use the JavaScript as a straight up jQuery plugin without using the HTML output helper.

Copy the JavaScript file (lib/generators/responsive_image_tag/templates/responsive-image-tag.js) to your JavaScript folder and make sure your HTML structure matches that documented.

Usage

You need to do two things. First, make sure that you include a reference to the JavaScript file in your layout:

<%= javascript_include_tag "responsive-image-tag" %>

After that, you can use the new tag like so, in a view:

<%= responsive_image_tag("small.jpg", "big.jpg", :alt => "Alt text", :class => "css-class") %>

This will generate HTML like so:

<span class="img-placeholder"></span>
<noscript data-fullsrc="big.jpg" data-mobilesrc="small.jpg" class="responsivize" data-alttext="Alt text" data-cssclass="css-class">
  <img alt="Alt text" class="css-class" src="big.jpg" />
</noscript>

In order for the JavaScript image replacement to happen, you need to put the following mehtod call in a $(document).ready() block or where ever you are initialising your JavaScript code.

$(".responsivize").responsiveImageTag();

You can add an optional CSS class on the responsivized images. If you don’t specify one, it will default to ‘responsive’.

$(".responsivize").responsiveImageTag({cssClass: "scale-with-grid"});

CHANGELOG

0.3.x

  • Removed prototype support. If you use Prototype then install the last 0.2.6 version.

  • Added support for specifying css classes on responsivized images

  • Converted jQuery file into a jQuery plugin

  • Code users must now supply their own document.ready mechanism (either require.js or a document.ready())

To Do List

  • Make JavaScript framework independant (or in other words as straight up JavaScript!)

Contributing to responsive_image_tag

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet

  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it

  • Fork the project

  • Start a feature/bugfix branch

  • Commit and push until you are happy with your contribution

  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright © 2011 Dave Hrycyszyn, Mairead Buchan and Stuart Chinery - headlondon.com

See LICENSE.txt for further details.

About

Allows you to specify two images in a responsive_image_tag, and includes a javascript generator which will rewrite the DOM, requesting the correct image based on the screen size of the current client device.

Resources

License

Stars

Watchers

Forks

Packages

No packages published