• Stars
    star
    115
  • Rank 304,901 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated about 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Yet another lightweight, customisable responsive image solution

rwd.images.js

Yet another lightweight, customisable responsive image solution

Note: Better docs and demos are coming soon

I know what you're thinking. Aren't there enough responsive image solutions by now? Until <picture> is standard and we can use it everywhere, I'm going to say "no".

Why is this one any different?

I like to think that it's a best-of-all-worlds solution, which addresses the requirements that Mat Marquis lists in his article So, You're Writing A Responsive Images Script:

  • Only makes 1 request for the image's current situation.
  • Easily allows a <noscript> fallback for users without JavaScript. If JavaScript breaks then so does the script, but that goes for all non-native solutions.
  • It supports "art direction", ie. the ability to load "sources that make use of different cropping, zooming, and focal points".
  • It actually works in the real-world. I've been using early prototypes of the plugin internally at XO Digital, and have just included this in our latest soon-to-be-released project for a well-recognised brand.

In addition to the above, rwd.images.js:

  • Uses a familar CSS/media query syntax for determining the appropriate image src.
  • Can automatically convert pixel-based media queries to ems.
  • Supports high-DPI/retina versions when a consistent naming convention is used.
  • Supports fallback images for browsers that don't support media queries.
  • Supports lazy-loading of images.
  • Is not restricted to just <img> tags. It can be applied to any element (<div>s etc) for use as backgrounds.
  • Works using either a mobile-first or a desktop-down philosophy.
  • Has no dependencies, but when combined with enquire.js, is even easier to use and allows users to download and share images as expected.
  • Is only ~1.7 KB minified and gzipped.

OK. Show me how it works

rwd.images.js uses the .rwdimage class, a series of [data-rwdimage] attributes and "CSS" to set up a responsive image.

Since the plugin solves the responsive image problem with a background-image "workaround", by loading @WickyNilliams' enquire.js before rwd.images.js, the <img src> will also be set to the correct filename so users can share or download it.

When used with enquire.js

<img class="rwdimage" data-rwdimage="
	{ src: url(/images/4-by-3.jpg); },
	(min-width: 501px) { src: url(/images/16-by-9.jpg); }
" />

<!-- Also load the matchMedia polyfills -->
<script src="/js/enquire.min.js"></script>
<script src="/js/rwd.images.min.js"></script>
</body>

At its simplest, that's it!

So what's this doing?
  1. .rwdimage instructs the script that this image needs to be "made responsive".
  2. [data-rwdimage] is passed a comma-separated list of CSS-like rules without a selector:
    1. src is the path to the image that should be set for that breakpoint (or by default if no media query is used)

So, the <img>:

  • Will display 4-by-3.jpg by default; and
  • At 501px, will be switched to display 16-by-9.jpg.

Note that media queries in JavaScript do not behave identically to those in CSS. If you don't specify a max-width media query for the breakpoints, the image's src will not be replaced when resizing the browser from wide to narrow.

When used without enquire.js or as backgrounds on other elements

<img class="rwdimage" data-rwdimage="
	{ src: url(/images/4-by-3.jpg); padding-bottom: ratio(3/4); },
	(min-width: 501px) { src: url(/images/16-by-9.jpg); padding-bottom: ratio(9/16); }
" />

<script src="/js/rwd.images.min.js"></script>
</body>

The only difference here is the padding-bottom: ratio(y,x) property. The parameters get evaluated and converted in to an intrinsic percentage ratio. You can pass in the actual dimensions of the image, or break it down to its smallest fraction like I have here.

Taking it further

Now let's use some more of the options available in rwd.images.js:

<img class="rwdimage" data-rwdimage="
	{ src: url(/images/4-by-3.jpg); },
	(min-width: 501px) { src: url(/images/16-by-9.jpg); }
" data-rwdimage-fallback="
	{ src: url(/images/16-by-9.jpg); }
" data-rwdimage-em="true" data-rwdimage-retina="true" />

The <img>:

  • Will display 4-by-3.jpg by default
  • At 31.3125em (501 รท 16) will display 16-by-9.jpg
  • Will also display 16-by-9.jpg for the oldIE fallback (.ltie9)

So here we can see how em-based media queries, retina images and old IE can easily be supported using rwd.images.js with minimal effort.

Further still

Using the remaining [data-rwdimage-*] attributes, we can achieve even more:

  • [data-rwdimage-em-base]: To change the base font size for the calculation of media queries from 16px. Some developers like to set html { font-size: 62.5%; } so set -em-base to 10.
  • [data-rwdimage-fallback-class]: The class on html used to target the fallback browser. The default is ltie9, but you may like to set it to lt-ie9 or no-mq if using Modernizr to detect media query support.
  • [data-rwdimage-retina-suffix]: The suffix used for high-DPI/retina image filenames. The default is @2x. Filenames must follow the convention: [filename][suffix][extension].
  • [data-rwdimage-lazy-load]: Set to trueto only load the <img>'s relevant src when it has a class of lazy-loaded applied.

Note: If using enquire.js and [data-rwdimage-lazy-load="true"]to lazy-load images, you must also call window.rwdImageChangeSrc(img) when applying the .lazy-loaded class.

Something like:

<script src="/js/enquire.min.js"></script>
<script src="/js/rwd.images.min.js"></script>
<script>
(function() {
	// Get all images
	var $images = document.getElementsByClassName('rwdimage');
	
	var lazyLoad = function($image) {
		$image.className += ' lazy-loaded';
		window.rwdImageChangeSrc($image);
	};
	
	// Lazy-load them all (don't use this in production!)
	for (var i = 0; i < $images.length; i++) {
		lazyLoad($images[i]);
	}
})();
</script>

Things to note

If not using enquire.js, there may be times where your image is outside of a container that constrains its size. This will lead to the image continuing to scale past its original, and intended maximum size.

To prevent this, set a relevant breakpoint to reset the image's dimensions, and also apply it to the fallback if appropriate:

<img class="rwdimage" data-rwdimage="
	{ src: url(/images/4-by-3.jpg); padding-bottom: ratio(3/4); },
	(min-width: 501px) { src: url(/images/16-by-9.jpg); padding-bottom: ratio(9/16); }
	(min-width: 1000px) { height: 562px; padding-bottom: 0; width: auto; }
" data-rwdimage-fallback="
	{ src: url(/images/16-by-9.jpg); height: 562px; padding-bottom: 0; width: auto; }
" />

Copyright (c) 2014 Matt Stow
Licensed under the MIT license (see LICENSE for details)
Minified version created with Online YUI Compressor: http://www.refresh-sf.com/yui/

More Repositories

1

jQuery-rwdImageMaps

Responsive Image Maps jQuery Plugin
JavaScript
1,556
star
2

eqio

A simple, tiny alternative to element/container queries
JavaScript
429
star
3

dummys-guide-to-redux-and-thunk-react

Tutorial post
JavaScript
321
star
4

react-native-svg-icon

A simple, but flexible SVG icon component for React Native
JavaScript
177
star
5

RWD-Retrofit

Allows an existing desktop site to co-exist with a responsive site, while also able to serve the desktop site to a different breakpoint on "mobile"
JavaScript
104
star
6

Suzi

A mature, feature-rich, responsive Sass and Grunt UI framework
CSS
102
star
7

Layout-Engine

Adds the rendering engine name as a class on the html tag and returns a JavaScript object containing the vendor, version and browser name (where appropriate)
JavaScript
96
star
8

mqGenie

Adjusts CSS media queries in browsers that include the scrollbar width in the viewport width so they fire at the intended size
JavaScript
89
star
9

hucssley

Hucssley - a full-featured, consistent, atomic utility class library for rapidly building performant UI
SCSS
78
star
10

quench-vue

Simple, client-side hydration of pre-rendered Vue.js apps
JavaScript
75
star
11

elf

Elf is a simple & magical Eleventy starter kit to help you create a project using standard technologies like webpack, Babel and Sass, while also considering ease of use, performance and browser compatibility.
JavaScript
51
star
12

jQuery-rwdImages

Allows responsive content images using the redux spacer technique (http://mattstow.com/experiment/responsive-images-redux/responsive-images-redux-jquery-plugin.html) to be shared and saved
JavaScript
43
star
13

Viewport-Genie

Adds the real viewport width and height (in px and em) as an element on the body to help with obtaining values for responsive breakpoints
JavaScript
37
star
14

Class-Query

A simple method to help manage responsive content (and an alternative to element queries as an added bonus)
JavaScript
31
star
15

keyboard-focus

A rudimentary way to detect users that navigate with the Tab key
JavaScript
25
star
16

react-accessible-tabs

An accessible React tabs component
JavaScript
24
star
17

Adobe-Blank

Reduced/subset version to "English"-only characters
CSS
12
star
18

webpack-svg-icon-system

A loader and plugin for webpack that converts all your SVGs into symbols and merges them into a SVG sprite.
JavaScript
10
star
19

ikuno

A simple, Grunt image and SVG optimiser
JavaScript
10
star
20

react-native-bem

A tiny, fast, BEM-inspired method to styling React Native components
JavaScript
9
star
21

swinch.js

A lightweight, customisable, horizontal touch detection script
JavaScript
4
star
22

hucssley-hireup-demo

JavaScript
1
star
23

Suzi-Code-Hints

Adds code hint support for all of Suzi's mixins and functions: https://github.com/izilla/Suzi#mixins-and-functions
1
star
24

littlelink-blossoming

CSS
1
star
25

hireup-assets

1
star
26

github-pr-approvals

A Greasemonkey script to require approvals in GitHub PRs before merging is allowed
JavaScript
1
star
27

brackets-legibility

Increase the legibility of Brackets' UI. Useful for High DPI screens
CSS
1
star
28

hucssley-hireup-demo-vue

Vue
1
star
29

Not-Required

Removes all required field attributes to test form submissions
JavaScript
1
star
30

color-flashcards

A simple web app (in under 10kb gzipped) to help teach your children colors with both visual and audio cues.
JavaScript
1
star
31

simple-social-media

A simple, mock-social media, client-side Angular application
JavaScript
1
star
32

suzi.grid.js

A JavaScript implementation of Suzi's grid system for rapid development
JavaScript
1
star