├── .htaccess ├── .repo-rt ├── README.md ├── demo.html ├── responsiveimgs.js ├── responsiveimgs.min.js └── sample-content ├── photocred.txt ├── running-lrg.jpg └── running-sml.jpg /.htaccess: -------------------------------------------------------------------------------- 1 | # Responsive Images 2 | # Mobile-First images that scale responsively and responsibly 3 | # Copyright 2010, Scott Jehl, Filament Group, Inc 4 | # Dual licensed under the MIT or GPL Version 2 licenses. 5 | # //Start Responsive Images 6 | RewriteEngine On 7 | # direct image requests to temp 8 | RewriteCond %{QUERY_STRING} full=(.*)&? 9 | RewriteRule (.*)rwd-router/.*\.(jpe?g|png|gif|webp) $1%1 [L] 10 | # ignore trap for non-image requests, rewrite URL without trap segment 11 | RewriteRule (.*)rwd-router/(.*)$ $1$2 12 | # //End Responsive Images -------------------------------------------------------------------------------- /.repo-rt: -------------------------------------------------------------------------------- 1 | RETIRED 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :warning: This project is archived and the repository is no longer maintained. 2 | 3 | We recommend you use picturefill instead. https://github.com/scottjehl/picturefill 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | # Old Readme, kept for historic purposes: 23 | 24 | ## Responsive Images 25 | ### An Experiment with Mobile-First Images that Scale Responsively & Responsibly 26 | 27 | 28 | 29 | 30 | 31 | #### What is this? 32 | The goal of this technique is to deliver optimized, contextual image sizes in [responsive layouts](http://www.alistapart.com/articles/responsive-web-design/) that utilize dramatically different image sizes at different resolutions. Ideally, this could enable developers to start with mobile-optimized images in their HTML and specify a larger size to be used for users with larger screen resolutions -- without requesting both image sizes, and without UA sniffing. 33 | 34 | 35 | ### Instructions 36 | ##### * Note: you'll need an apache web server for this to work. 37 | 38 | 1. Add the ".htaccess"" file* to your web server public rootfile's head (OR if you already have an .htaccess file, you can paste its contents into your existing file) 39 | 40 | 2. Grab "responsiveimgs.min.js" and reference it from your HTML in the HEAD of your document: 41 | 42 | 43 | 44 | 3. For any img elements that offer a larger desktop-friendly size, reference the larger image's src via a ?full= query string on the image url. Note that the path after ?full= should be written so it works directly as the src attribute as well (in other words, include the same path info you need for the small version) 45 | 46 | <img src="small.jpg?full=large.jpg" > 47 | 48 | 49 | #### How's it work? 50 | As soon as rwd-images.js loads, it tests the screen width, and if it's large, it inserts a BASE element into the head of your page, directing all subsequent image, script, and stylesheet requests through a fictitious directory called "/rwd-router/". As these requests reach the server, the .htaccess file determines whether the request is a responsive image or not (does it have a ?full query parameter?). It redirects responsive image requests immediately to their full size, while all non-responsive-image requests go to their proper destination through a URL rewrite that ignores the "/rwd-router/" segment. 51 | 52 | ### Supported Browsers 53 | Safari (desktop, iPhone, iPad), Chrome, Internet Explorer (8+), Opera. Firefox 4 54 | 55 | ### Support Caveats: 56 | Firefox 3.6-, IE 6/7, etc 57 | ##### Note: 58 | Unsupported browsers still receive responsive images; the drawback is that both image sizes are requested, so there's additional overhead on the initial request on the desktop. That aside, subsequent page visits can make use of a cookie that is set in all browsers to serve the appropriate size from the start. 59 | 60 | ### Non-Javascript Browsers 61 | Non-javascript enabled/supporting browsers/devices will receive the initial image referenced in the image src attribute (the mobile version) 62 | 63 | ### Optional Configuration and Optimizations: 64 | 65 | 1 option is available for external configuration: widthBreakPoint. You can set it within a global "rwd_images" object that must be defined before rwd-images.js is loaded. 66 | 67 | 71 | 72 | ### Setting a different width breakpoint 73 | If you'd like to use a different width breakpoint than the 480px default: 74 | 75 | 82 | 83 | 84 | #### Server-side Optimizations 85 | A cookie is set by the script so that on subsequent page loads you can set your images an appropriate source from the start and 86 | choose not to load the script at all. 87 | 88 | The cookie looks like this (where 1440 is the screen resolution): 89 | "rwd-resolution=1440" 90 | 91 | #### License & Disclaimer 92 | - Dual licensed under the MIT or GPL Version 2 licenses. 93 | - Copyright 2010, Scott Jehl & Filament Group, Inc 94 | - This project is experimental. Please fork and contribute! 95 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Responsive Images Test Page 6 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 |

Responsive Images Test Page

27 |

In supported browsers, the following image will load either small or large version depending on screen resolution, making a single 1kb request before requesting the appropriate size.

28 | 29 | 30 | 31 |

Photo credit (CC): Cia de Foto Flickr Creative Commons

32 | 33 | 34 | -------------------------------------------------------------------------------- /responsiveimgs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Responsive Images: Mobile-First images that scale responsively and responsibly 3 | * Copyright 2011, Scott Jehl, Filament Group, Inc 4 | * Dual licensed under the MIT or GPL Version 2 licenses. 5 | */ 6 | (function( win ){ 7 | //defaults / mixins 8 | var rwdi = win.rwd_images || {}, 9 | widthBreakPoint = rwdi.widthBreakPoint || 480, 10 | htmlClass = "rwd-imgs-lrg", 11 | wideload = win.screen.availWidth > widthBreakPoint, 12 | filePath = location.href, 13 | dirPath = filePath.substring( 0, filePath.lastIndexOf( "/" ) ) + "/", 14 | doc = win.document, 15 | head = doc.getElementsByTagName( "head" )[0], 16 | 17 | //record width cookie for subsequent loads 18 | date = new Date(); 19 | date.setTime(date.getTime()+(5/*5 sec*/*1000)); 20 | doc.cookie = "rwd-resolution=" + screen.width + ";expires=" + date.toGMTString() +"; path=/"; 21 | 22 | //if wideload is false quit now 23 | if( !wideload ){ 24 | return; 25 | } 26 | 27 | //add HTML class 28 | doc.documentElement.className += " " + htmlClass; 29 | 30 | //base tag support test (returns base tag for use if support test passes) creds: jQuery Mobile, hasJS 31 | var base = (function(){ 32 | var backup, 33 | baseAdded = false, 34 | a = doc.createElement("a"), 35 | supported = false, 36 | base = head.getElementsByTagName( "base" )[0] || (function(){ 37 | baseAdded = true; 38 | return head.insertBefore( doc.createElement("base"), head.firstChild ); 39 | })(); 40 | 41 | backup = !baseAdded && base.href; 42 | 43 | //test base support before using 44 | base.href = location.protocol + "//" + "x/"; 45 | a.href = "y"; 46 | 47 | //if dynamic base tag is unsupported (Firefox) 48 | if( a.href.indexOf( "x/y" ) < 0 ){ 49 | if( backup ){ 50 | base.href = backup; 51 | } 52 | else{ 53 | head.removeChild(base); 54 | } 55 | base = null; 56 | } 57 | else{ 58 | base.href = dirPath + "rwd-router/"; 59 | } 60 | //return 61 | return base; 62 | })(), 63 | 64 | //find and replace img elements 65 | findrepsrc = function(){ 66 | for( var i = 0, imgs = doc.getElementsByTagName( "img" ), il = imgs.length; i < il; i++){ 67 | var img = imgs[i], 68 | src = img.getAttribute( "src" ), 69 | full = src.match( /(\?|&)full=(.*)&?/ ) && RegExp.$2; 70 | 71 | if( full ){ 72 | img.src = full; 73 | } 74 | } 75 | }, 76 | 77 | //flag for whether loop has run already 78 | complete = false, 79 | 80 | //remove base if present, find/rep image srcs if wide enough (maybe make this happen at domready?) 81 | readyCallback = function(){ 82 | if( complete ){ return; } 83 | complete = true; 84 | 85 | if( !base ) { 86 | findrepsrc(); 87 | } 88 | else{ 89 | head.removeChild(base); 90 | } 91 | }; 92 | 93 | //DOM-ready or onload handler 94 | //W3C event model 95 | if ( doc.addEventListener ) { 96 | win.addEventListener( "load", readyCallback, false ); 97 | } 98 | // If IE event model is used 99 | else if ( doc.attachEvent ) { 100 | win.attachEvent( "onload", readyCallback ); 101 | } 102 | })(this); -------------------------------------------------------------------------------- /responsiveimgs.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Responsive Images: Mobile-First images that scale responsively and responsibly 3 | * Copyright 2011, Scott Jehl, Filament Group, Inc 4 | * Dual licensed under the MIT or GPL Version 2 licenses. 5 | */ 6 | (function(g){var k=g.rwd_images||{},d=k.widthBreakPoint||480,h="rwd-imgs-lrg",f=g.screen.availWidth>d,e=location.href,l=e.substring(0,e.lastIndexOf("/"))+"/",m=g.document,j=m.getElementsByTagName("head")[0],c=new Date();c.setTime(c.getTime()+(5*1000));m.cookie="rwd-resolution="+screen.width+";expires="+c.toGMTString()+"; path=/";if(!f){return}m.documentElement.className+=" "+h;var b=(function(){var r,q=false,p=m.createElement("a"),o=false,s=j.getElementsByTagName("base")[0]||(function(){q=true;return j.insertBefore(m.createElement("base"),j.firstChild)})();r=!q&&s.href;s.href=location.protocol+"//x/";p.href="y";if(p.href.indexOf("x/y")<0){if(r){s.href=r}else{j.removeChild(s)}s=null}else{s.href=l+"rwd-router/"}return s})(),n=function(){for(var r=0,t=m.getElementsByTagName("img"),p=t.length;r