Documentation
Overview
Response JS is a lightweight jQuery (or Zepto) plugin that gives web designers tools for building performance-optimized, mobile-first responsive websites. It provides semantic ways to dynamically swap code blocks based on breakpoints and serve images (or other media) progressively via HTML5 data attributes. Its methods give developers hooks for triggering responsive actions and booleans for testing responsive properties.
Setup
Create Sets
Response's most powerful feature is breakpoint-based data attribute sets. Designers can choose custom breakpoints and create only the data attributes they need. The recommended setup method is to add data-responsejs
to your <body>
tag with the parameters formatted as JSON as shown below. (Hint: Use JSONLint to validate your JSON.)
Data attribute set setup via JSON
<body data-responsejs='{
"create": [
{ "breakpoints": [0,320,481,641,961,1025,1281],
"mode": "src", "prefix": "src" },
{ "breakpoints": [0,320,481,641,961,1025,1281],
"mode": "markup", "prefix": "r" }
]}
'
>
If you cannot edit your <body>
tag, you can setup the data attributes from JavaScript by using Response.create
directly (after the plugin is loaded). Either way the options are the same. The breakpoints
parameter is optional. The ones shown above are the defaults for width-based sets and are ideal mins for working with 960 grids.
Load Files
Load jQuery (ver. 1.7 or higher) and Response in your <head>
or—better—just before your </body>
tag. Use normal external <script>
tags or an asynchronous loader like Modernizr.load
a.k.a. Yepnope
. In WordPress, use wp_enqueue_script
. Examples of all 3 are below. (Tip: Use versioned filenames, such as response.0.2.8.min.js)
Load w/ external <script>
tags
<script src="/path/to/jquery.min.js"></script>
<script src="/path/to/response.min.js"></script>
Load w/ Modernizr.load
Modernizr.load({
load: [
"/path/to/jquery.min.js",
"/path/to/response.min.js"
]
});
Load in WordPress
wp_enqueue_script( 'response', '/path/to/response.min.js', array('jquery'), '0.2.7', true ); #wp
Usage
Modes
- src
- Applies to
<img>
's and other elements that use thesrc
attribute. Use src mode when you want to serve different resolution media to different breakpoint ranges. - markup
- Applies to elements that support inner markup (elements that don't self close). Use markup mode when you want to serve different code blocks to different breakpoint ranges.
Examples
src mode
src mode ▰ applies to elements that use the src
attribute.
<-- Load lo-fi.png when viewport is 0–480px wide or no-js.
Load medium.png when viewport is 481–1024px wide.
Load hi-fi.png when viewport is 1025px+ wide. -->
<img src="lo-fi.png" data-src481="medium.png" data-src1025="hi-fi.png" alt="example" />
Consider wrapping <img>
tags in an <a>
tag that links to the larger version. This allows two versions of the image to be accessible in more situations without compromising performance.
src mode ▰ consider wrapping images in links.
<a href="hi-fi.png"><img src="lo-fi.png" data-src1025="hi-fi.png" alt="example" /></a>
An important src mode caveat is that screens fitting the hi-fi band(s) will briefly start to load the lo-fi image and then switch to the higher one. This occurs during the time that jQuery and Response are loaded and parsed. To circumvent this switchover you can use markup mode instead and include the entire <img>
tag inside the data attribute.
markup mode
markup mode ▰ applies to elements that support inner markup.
<-- Keep default when viewport is <320px wide or no-js.
Load data-r320 when viewport is 320–960px wide.
Load data-r961 when viewport is 961px+ wide. -->
<div data-r320="markup @ 320+" data-r961="markup @ 961+">default</div>
Best practices in markup mode:
- Default markup should be lightweight, and the data attribute(s) should be used to serve richer (heavier) content to capable screens. Think mobile first.
- Default markup can be empty. But for accessibility, semantics, and SEO, consider using a text-only-ish default, which if needed you could hide/unhide via CSS media queries.
- Escape quotes in attribute values as needed to prevent quote mismatches.
markup mode ▰ in markup mode, HTML can be swapped.
<a
href="hi-fi.png"
data-r320='<img src="lo-fi.png" alt="image @ 320+">'
data-r961='<img src="hi-fi.png" alt="image @ 961+">'
>
text-only link @ <320px and no-js
</a>
Ideal uses for markup mode:
- Load sidebars only for screens wide enough to fit them.
- Load images only for screens above a certain breakpoint—with a non-image fallback. (On a blog, you could load article headlines on small screens and add thumbnails to screens above a breakpoint.)
markup mode escape quotes in data attributes as needed!
GOOD: data-r0="<a id='myid'>here is text</a>"
GOOD: data-r0="<a id="myid">here's text</a>"
GOOD: data-r0='<a id="myid">here's text</a>'
FAIL: data-r0='<a id="myid">here's text</a>'
CMS Integration
In CMS implementations or other situations where markup mode inputs are dynamic, you'll surely need some sort of escaping function, such as PHP's htmlspecialchars()
or WordPress' esc_attr()
.
Methods
Response provides useful booleans for quickly testing screen properties that matter when building responsive websites (such as width, height, and device pixel ratio) and an easy-to-use event hook for triggering responsive actions. Methods work in all JavaScript-enabled browsers unless noted otherwise. // New methods were added in version 0.3.0. I haven't had time to update these docs yet, but click here to see a full overview.
Booleans
Response.band(minWidth, maxWidth)
/**
* Response.band tests if a min/max-width breakpoint range is active.
*
* @param integer minWidth is a min-width in pixels. (required)
* @param integer maxWidth is a max-width in pixels. (optional)
*
* @return boolean
*/
Response.band(481) // true in viewports 481px wide and up.
Response.band(0, 480) // true in viewports 0-480px wide.
Response.wave(minHeight, maxHeight)
/**
* Response.wave tests if a min/max-height breakpoint range is active.
*
* @since 0.2.9
*
* @param integer minHeight is a min-height in pixels. (required)
* @param integer maxHeight is a max-height in pixels. (optional)
*
* @return boolean
*/
Response.wave(641) // true in viewports 641px high and up.
Response.wave(0, 640) // true in viewports 0-640px high.
Response.dpr(ratio)
Test if a given device-pixel-ratio is active. (Applies to Webkit, Android, Opera (Presto 2.8+), Gecko/Firefox.)
@param | decimal | ratio | is the device-pixel-ratio to test for. |
@return | boolean | true if the device's device-pixel-ratio is at or above the specified ratio. Otherwise false (it's less or untestable). |
@example
Response.dpr(1.5) // true when device-pixel-ratio is 1.5+
Response.dpr(2) // true when device-pixel-ratio is 2+
Hooks
Response.action(callback)
A hook for calling functions on both the ready and resize events.
@param callback|array is the callback or array of callbacks
@example Response.action( function () {
/* stuff to do on ready and resize */
});
@example Response.action(myFunc1); // call myFunc1() on ready/resize
@example Response.action([myFunc1, myFunc2]); // call myFunc1(), myFunc2() ...
Manual Setup
For situations where you don't want to put JSON on your body tag, you can use the Response.create
method to manually create data attribute sets from JavaScript.
Response.create(options)
@param | object | options | an object containing the setup options |
@param | string | options.mode | the mode (either 'markup' or 'src') |
@param | string | options.prefix | a unique prefix to be used as the data- key. Can be alphanumerics, dashes, and/or underscores. A unique prefix must be used for each attribute set. The prefix is used to create attributes of the form data-myprefix320, data-myprefix481, etc. where 'myprefix' is the set's prefix. |
@param | string | options.prop | property to base breakpoints on. Available props are 'width' (default) and 'device-pixel-ratio' |
@param | array | options.breakpoints | an array of min- breakpoints. Default breakpoints depend on prop. See the source. |
@example To achieve the same setup as the JSON setup used for all the usage examples on this page, you'd do this:Response.create({ mode: 'markup', prefix: 'r', breakpoints: [0,320,481,641,961,1025,1281] }); Response.create({ mode: 'src', prefix: 'src', breakpoints: [0,320,481,641,961,1025,1281] });
@example Since [0,320,481,641,961,1025,1281] are the default breakpoints for the width prop (ideal for working with 960 grids) we could also just do this:Response.create({ mode: 'markup', prefix: 'r' }); Response.create({ mode: 'src', prefix: 'src' });
@example Createdevice-pixel-ratio
based attributes:Response.create({
which would create src mode functionality for these attributes:
mode: 'src',
prefix: 'density',
prop: 'device-pixel-ratio',
breakpoints: [1, 1.5, 2]
});
data-density1
#device-pixel-ratio
≥ 1data-density1.5
#device-pixel-ratio
≥ 1.5data-density2
#device-pixel-ratio
≥ 2
Closures
It is recommended that you wrap custom code in a self-invoking anonymous function. This design pattern has several advantages. Watch this video to learn more. It looks like this:
(function(window, document, $, R) { // put the vars you need and match them at the bottom
// All 4 vars are localized in here - makes them read faster b/c they are in local scope
// $ works as alias for jQuery in here - ensures no conflict with other libs
// R works as alias for Response in here - R.band(320) instead of Response.band(320)
// window and document minify down to single letter vars
}(this, this.document, this.jQuery, this.Response)); // in global scope, this === window