Documentation
Overview
Response is an experimental jQuery plugin for building websites with responsive content. It can dynamically swap content based on breakpoints and data attributes.
Breakpoint Sets
Response's most powerful feature is breakpoint sets. Using the sets, content for more-capable devices and/or larger viewports can be stored in HTML5 data attributes. Designers can create custom sets to make exactly the functionality that they want. (None are setup by default.)
Write markup like:
<div
data-min-width-320='<img src=lo-fi.png alt="image @ 320+ viewports">'
data-min-width-961='<img src=hi-fi.png alt="image @ 961+ viewports">'
>
text-only @ <320px and no-js
</div>
Or load a different src:
<-- Load lo-fi.png for devices 0–640px wide or no-js.
Load hi-fi.png for devices 641px+ wide. -->
<img src="lo-fi.png" data-min-device-width-641="hi-fi.png" alt="example">
Breakpoints can be based on width | device-width | height | device-height | device-pixel-ratio or on custom props. Designers can use the default breakpoints (ideal for 960 grids) or specify custom breakpoints.
Using JSON as shown below is the simplest way to create sets. Sets can also be created in JavaScript using Response.create. In either case, the options are the same.
JSON setup example
<body data-responsejs='{
"create": [{
"prop": "width",
"prefix": "min-width- r src",
"breakpoints": [0, 320, 481, 641, 961, 1025, 1281]
}]
}'>
Use custom breakpoints or use the default breakpoints:
- width / device-width:
[0, 320, 481, 641, 961, 1025, 1281]
- height / device-height:
[0, 481]
- device-pixel-ratio:
[1, 1.5, 2]
Modes
Elements behave in one of two modes—markup or src. Since version 0.3.0 modes are autodetected and it is only necessary to create one breakpoint set to accomodate both. (0.2.x devs should note that it is more efficient to create a set with prefix aliases such as "prefix": "r src"
rather than creating a separate set for each mode. Either techniques works. The 0.3.0 and 0.3.1 change notes expand on this, and, if needed, the old docs are still online.)
The difference between the modes lies in the content that is swapped. In src mode, the src
attribute is swapped. In markup mode, the innerHTML is swapped. Markup mode has more extensive capabilities because entire code blocks can be swapped.
img
| input
| source
| embed
| track
elements always behave in src mode.
iframe
| audio
| video
behave in src mode only if a src
attribute is present.
Otherwise elements behave in markup mode.
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-min-width-320='<img src=lo-fi.png alt="image @ 320+">'
data-min-width-961='<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.)
Escape Quotes in Data Attributes
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()
.
API (0.6)
Response provides cross-browser compatible ways to get and test properties that matter when building responsive websites, an HTML5 dataset implentation, event hooks for responsive actions, and related utilities. An API overview is below. Additional documention is on Github and in the test suite.
Getters
Response.deviceMax() // Get the calculated Math.max(deviceW, deviceH)
- @example jsfiddle.net/eKHWF/5/
- @return number
Response.deviceMin() // Get the calculated Math.min(deviceW, deviceH)
- @example jsfiddle.net/eKHWF/5/
- @return number
Response.viewportW() // Get the current viewport width.
- @example jsfiddle.net/eKHWF/5/
- @return number
Response.viewportH() // Get the current viewport height.
- @example jsfiddle.net/eKHWF/5/
- @return number
Response.scrollX() // cross-broswer equivalent to native window.scrollX
- @return number
Response.scrollY() // cross-broswer equivalent to native window.scrollY
- @return number
Booleans
Response.band(min [, max]) // Test if a viewport min/max-width range is active.
- @param integer min
- is a min-width in pixels.
- @param integer max
- is a max-width in pixels.
- @return boolean
Response.band(481) // true in viewports 481px wide and up.
Response.band(0, 480) // true in viewports 0-480px wide.
Response.wave(min [, max]) // Test if a viewport min/max-height range is active.
- @param integer min
- is a min-height in pixels.
- @param integer max
- is a max-height in pixels.
- @return boolean
Response.wave(481) // true in viewports 481px high and up.
Response.wave(0, 480) // true in viewports 0-480px high.
Response.device.band(min [, max]) // Test if a min/max-device-width range is active.
- @param integer min
- is a min-width in pixels.
- @param integer max
- is a max-width in pixels.
- @return boolean
Response.device.band(481) // true for devices 481px wide and up.
Response.device.band(0, 480) // true for devices 0-480px wide.
Response.device.wave(min [, max]) // Test if a min/max-device-height range is active.
- @param integer min
- is a min-height in pixels.
- @param integer max
- is a max-height in pixels.
- @return boolean
Response.device.wave(481) // true for devices 481px high and up.
Response.device.wave(0, 480) // true for devices 0-480px high.
Response.dpr(ratio) // Get the device-pixel-ratio, or test if a given device-pixel-ratio is active.
- @param number ratio
- is a
device-pixel-ratio
to test (integer or float)
- @return number|boolean
Response.dpr() // get device-pixel-ratio (returns 0 if undetectable)
Response.dpr(1.5) // true when device-pixel-ratio is 1.5+
Response.dpr(2) // true when device-pixel-ratio is 2+
Response.media(query) // Get window.matchMedia || window.msMatchMedia || {}
This is a browser-normalized generic method designed for when none of the above booleans apply. It uses the same syntax as window.matchMedia and falls back gracefully when not supported. The booleans above (band, wave, etc.) are faster and better supported than this method (although you can polyfill matchMedia before Response is loaded to improve support).
- @param string query
- is a media query to test.
- @return object
- The .matches prop is boolean (or undefined if neither form is supported).
Response.media("(min-width: 20em)").matches // true in viewports 20em+ wide.
Response.inViewport(elem [, verge]) // Test if any part of an element is in the viewport.
- @param object elem
- is a native DOM element or jQuery object to test.
- @param number verge
- is the # extra pixels around elem to also test. (Defaults to 0)
- @return boolean
- @example responsejs.com/test/
Response.inViewport(this) // true if any part of this is in the viewport (exact).
Response.inViewport(this, 100) // true if any part of this is in (or 100px near) the viewport.
Response.inViewport(this) === Response.inX(this) && Response.inY(this) // always true
Response.inX(elem [, verge]) // Test if any part of elem is in the same x-axis as the viewport.
- @param object elem
- is a native DOM element or jQuery object to test.
- @param number verge
- is the # extra pixels around elem to also test. (Defaults to 0)
- @return boolean
- @example responsejs.com/test/
Response.inX(this) // true if any part of this is in same x-axis as the viewport (exact).
Response.inX(this, 100) // true if any part of this is in (or 100px near) the same x-axis.
Response.inViewport(this) === Response.inX(this) // true if there is no vertical overflow
Response.inY(elem [, verge]) // Test if any part of elem is in the same y-axis as the viewport.
- @param object elem
- is a native DOM element or jQuery object to test.
- @param number verge
- is the # extra pixels around elem to also test. (Defaults to 0)
- @return boolean
- @example responsejs.com/test/
Response.inY(this) // true if any part of this is in same y-axis as the viewport (exact).
Response.inY(this, 100) // true if any part of this is in (or 100px near) the same y-axis.
Response.inViewport(this) === Response.inY(this) // true if there is no horizontal overflow
Events
Response.ready(fn) // Call function when the DOM is ready.
- @param callback fn
- is a function to call on ready.
Response.ready(function(){ /* stuff to do on ready */ });
Response.resize(fn) // Call function whenever the window (viewport) resizes.
- @param callback fn
- is a function to call on the resize event.
Response.resize(function(){ /* stuff to do on resize */ });
Response.action(fn) // Call function when the DOM is ready and whenever the window resizes.
- @param callback fn
- is a function to call on ready and resize.
Response.action(function(){ /* stuff to do on ready and resize */ });
Response.crossover(fn [, prop]) // Call function when breakpoint sets' breakpoints are crossed.
- @param callback fn
- is a function to call on the crossover custom event.
- @param string prop
- is a specific prop's breakpoints to target. Defaults to all.
Response.crossover(function(){ /* stuff to do on all breakpoint set crossovers */ });
Response.crossover(function(){ /* stuff to do on "width" crossovers */ }, "width");
Dataset
Note: The dataset methods in Response 0.7+ come from dope.
Response.dataset(elem [, key, value]) // Get or set custom data- attributes.
- @param object elem
- is a native DOM element or jQuery element.
- @param string|mixed key
- is the camelCase (or lowercase) identifier for the data.
- @param string|mixed value
- is the data value to store.
- @return mixed
Response.dataset(el, "showName", "Lost") // Set data-show-name on el to "Lost"
Response.dataset(el, "seasonNumber", 1) // Set data-season-number on el to "1"
Response.dataset(el, {seasonNumber: 1, episode: 5}) // Set multiple data attrs at once.
Response.dataset(el, "showName", "Lost") // Set data-show-name on el to "Lost"
Response.dataset(el, "showName") // Get data-show-name // "Lost"
Response.dataset(el, "seasonNumber") // Get data-season-number // "1"
Response.dataset(el, ["seasonNumber"]) // Get and render data-season-number // 1
Response.dataset(el) // Get object containing all data attrs on el element.
Response.dataset(el).showName // "Lost"
Response.dataset($(".shows"), "genre", "drama") // Set data-genre to "drama" on all shows
Response.deletes(elem, keys) // Remove custom data- attributes.
- @param object elem
- is a native DOM element or jQuery element.
- @param string keys
- is one or more space-separated keys to remove.
Response.deletes(el, "showName") // Remove data-show-name from el.
Response.deletes(el, "showName seasonNumber") // Remove both data attrs from el.
Response.deletes($(".shows"), "genre") // Remove data-genre from all shows.
$.fn.dataset([key, value]) // Get or set custom data- attributes.
This is a jQueryish form of the dataset method. To enable it, first call Response.bridge(jQuery).
$("#lost").dataset("showName", "Lost") // Set data-show-name on #lost to "Lost"
$("#lost").dataset("seasonNumber", 1) // Set data-season-number on #lost to "1"
$("#lost").dataset({seasonNumber: 1, episode: 5}) // Set multiple data attrs at once.
$("#lost").dataset("showName", "Lost") // Set data-show-name on this to "Lost"
$("#lost").dataset("showName") // Get data-show-name // "Lost"
$("#lost").dataset("seasonNumber") // Get data-season-number // "1"
$("#lost").dataset(["seasonNumber"]) // Get and render data-season-number // 1
$("#lost").dataset() // Get object containing all data attrs on #lost.
$("#lost").dataset().showName // "Lost"
$(".shows").dataset("genre", "drama") // Set data-genre to "drama" on all shows.
$(".shows").dataset("genre") // Get data-genre of the first element in the set. // "drama"
$.fn.deletes(keys) // Remove custom data- attributes.
This is a jQueryish form of the deletes method. To enable it, first call Response.bridge(jQuery).
$("#lost").dataset("showName") // Remove data-show-name from el.
$("#lost").dataset("showName seasonNumber") // Remove both data attrs from el.
$(".shows").dataset($("genre") // Remove data-genre from all shows.
Extending
Response.create(options) // Create breakpoint sets.
- @param object|array options
- is an object (or array of objects) specifying options for the set(s).
- options.prop (string)
- is the property to base breakpoints on. Supported props are width|height|device-width|device-height|device-pixel-ratio. Custom props can be added via Response.addTest(). Default:
"width"
- @param string options.prefix
- is a prefix to use in the data- key. It can be alphanumerics, dashes, and/or underscores. A unique prefix must be used for each set. Prefixes create attribute names of the form
data-myprefix320
,data-myprefix481
, etc. Since 0.3.1 it is possible to define multiple (aliased) prefixes in a space-separated string. Default: "min-[prop]-" (e.g. if the prop is "width" then the prefix would default to "min-width-")
- @param array options.breakpoints
- is an array of
min-
breakpoints. Defaults depend on the prop. See here.
Response.bridge($) // Integrate .dataset/.deletes into $.fn
Optional methods added by Response.bridge($)
are: dataset and deletes. To use these optional methods simply call Response.bridge($)
before you need them. (It only needs to be called once.)
Response.addTest(prop, fn) // Add a custom test for use in breakpoint sets.
- @param string prop
- is a custom prop name (or an existing prop to override).
- @param callback fn
- is a boolean callback to test min breakpoints for prop.
Response.addTest("viewport-area", function(min) {
return min >= Response.viewportW() * Response.viewportH();
}).create({
prop: "viewport-area" // custom prop name
, breakpoints: [100000, 1000000, 10000000] // custom breakpoints
, dynamic: true // set this to true if prop needs to be tested on resize
});
Comments
The Disqus thread has been removed but is readable at responsejs.disqus.com. The best way to ask a question is to create an issue via Github or tweet to @ryanve