Multiple breakpoint responsive images loaded with Javascript for ExpressionEngine
Pull request Compare This branch is 5 commits ahead, 4 commits behind joshje:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Responsive Image

The script checks if an image is larger than a specified width, then loads in a higher resolution image. It compares the current viewport width to an array of user set breakpoints then updates the src to the most appropriately sized image. This is an ExpressionEngine focussed implementation, but can be adapted easily for use in other systems.


  • Adhering the the principles of mobile first the smallest image is included in the markup
  • We use an id="responsiveimage" on theimg element to trigger the script
  • No need for additional class or data attributes pointing to other image sources
  • Don’t forget the absolutely necessary img { width: 100% }
  • User sets the breakpoint values in the array to match the image options they have prepared
  • Assumes image paths such as /img/_320/image-name.ext and /img/_768/image-name.ext
  • Script compares the viewport width to the user set breakpoints in the script
  • Script switches the path to the most appropriately sized image, using a regexp


The reference to being ExpressionEngine specific refers to the use of the Image Manipulations within EE’s File Upload Preferences. Four copies of the image have been created automatically, constrained to widths of 320, 480, 768 and 980px for this example. Because the manipulations are stored in directories, our focus shifts to changing the path.


Inspiration from Automatic Responsive Images in WordPress by Keir Whitaker. Based on the elegant Responsive-Enhance by Josh Emerson. Justification for a double download from Image-y Nation by Jeremy Keith. Path changing regex magic provided by Myles Eftos.


<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8" />
        img {
            width: 100%;
    <title>Responsive Image</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <img id="responsiveimg" src="img/_320/bodalla-cheese-factory.jpg" alt="Responsive Image" />
<script src="responsiveimage.js"></script>
    responsiveImage(document.getElementById('responsiveimg'), 320);


var addEvent=function(){return document.addEventListener?function(a,c,d){if(a&&a.nodeName||a===window)a.addEventListener(c,d,!1);else if(a&&a.length)for(var b=0;b<a.length;b++)addEvent(a[b],c,d)}:function(a,c,d){if(a&&a.nodeName||a===window)a.attachEvent("on"+c,function(){return,window.event)});else if(a&&a.length)for(var b=0;b<a.length;b++)addEvent(a[b],c,d)}}();

var responsiveImage = function(img, width, monitor) {

    var bp = [320, 480, 524, 768, 980];
    var src = img.src;
    var size = '_' + bp[0];

    if (img.length) {
        for (var i = 0, len = img.length; i < len; i++) {
          responsiveImage(img[i], width, monitor);
    else {
        for (var i = 0; i < bp.length - 1; i++) {
            if (img.clientWidth > bp[i]) {
                size = '_' + bp[i+1];
        var responsiveimg = new Image();
        addEvent(responsiveimg, 'load', function(e) {
            img.src = this.src;
        responsiveimg.src = src.replace(/(\/img\/)(_\d+)(\/.+)/, '$1' + size + '$3');
    if (monitor != false) {
        addEvent(window, 'resize', function(e) {
          responsiveImage(img, width, false);
        addEvent(img, 'load', function(e) {
          responsiveImage(img, width, false);