Skip to content

Commit

Permalink
changed picturefill to support span elements instead of div elements.…
Browse files Browse the repository at this point in the history
… This allows the picturefill module to act as inline content by default, much like a native img element.
  • Loading branch information
Scott Jehl committed Jun 6, 2013
1 parent 8525e26 commit 2509318
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 41 deletions.
64 changes: 32 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Picturefill

A Responsive Images approach that you can use today, that mimics the [proposed picture element](http://www.w3.org/community/respimg/wiki/Picture_Element_Proposal) using `div`s, for safety sake.
A Responsive Images approach that you can use today that mimics the [proposed picture element](http://www.w3.org/community/respimg/wiki/Picture_Element_Proposal) using `span`s, for safety sake.

* Author: Scott Jehl (c) 2012
* License: MIT/GPLv2

**Demo URL:** [http://scottjehl.github.com/picturefill/](http://scottjehl.github.com/picturefill/)

**Note:** Picturefill works best in browsers that support CSS3 media queries. It includes (externally) the [matchMedia polyfill](https://github.com/paulirish/matchMedia.js/) which makes matchMedia work in `media-query`-supporting browsers that don't have `matchMedia`, or at least allows media types to be tested in most any browser. `matchMedia` and the `matchMedia` polyfill are not required for `picturefill` to work, but they are required to support the `media` attributes on `picture` `source` elements.
**Note:** Picturefill works best in browsers that support CSS3 media queries. The demo page references (externally) the [matchMedia polyfill](https://github.com/paulirish/matchMedia.js/) which makes matchMedia work in `media-query`-supporting browsers that don't support `matchMedia`. `matchMedia` and the `matchMedia` polyfill are not required for `picturefill` to work, but they are required to support the `media` attributes on `picture` `source` elements. In non-media query-supporting browsers, the `matchMedia` polyfill will allow for querying native media types, such as `screen`, `print`, etc.

## Size and delivery

Expand All @@ -18,55 +18,55 @@ Currently, `picturefill.js` compresses to around 498bytes (~0.5kb), after minify
Mark up your responsive images like this.

```html
<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<div data-src="small.jpg"></div>
<div data-src="medium.jpg" data-media="(min-width: 400px)"></div>
<div data-src="large.jpg" data-media="(min-width: 800px)"></div>
<div data-src="extralarge.jpg" data-media="(min-width: 1000px)"></div>
<span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<span data-src="small.jpg"></span>
<span data-src="medium.jpg" data-media="(min-width: 400px)"></span>
<span data-src="large.jpg" data-media="(min-width: 800px)"></span>
<span data-src="extralarge.jpg" data-media="(min-width: 1000px)"></span>

<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<noscript>
<img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
</noscript>
</div>
</span>
```

Each `div[data-src]` element’s `data-media` attribute accepts any and all CSS3 media queries—such as `min` or `max` width, or even `min-device-pixel-ratio` for HD (retina) displays.
Each `span[data-src]` element’s `data-media` attribute accepts any and all CSS3 media queries—such as `min` or `max` width, or even `min-resolution` for HD (retina) displays.

### Explained...

Notes on the markup above...

* The `div[data-picture]` element's `alt` attribute is used as alternate text for the generated `img` element.
* The `div[data-picture]` element can have any number of `source` elements. The above example may contain more than the average situation would call for.
* Each `div[data-src]` element must have a `data-src` attribute specifying the image path.
* It's generally a good idea to include one source element with no `media` qualifier, so it'll apply everywhere.
* Each `data-src` element can have an optional `media` attribute to make it apply in different media settings. Both media types and queries can be used, like any `media` attribute, but support for media queries depends on the browser (unsupporting browsers fail silently).
* The `matchMedia` polyfill (included in `/external`) is necessary to support the `media` attribute across browsers, even in browsers that support media queries, although it is becoming more widely supported in new browsers.
* The `noscript` element wraps the fallback image for non-JavaScript environments, and including this wrapper prevents browsers from fetching the fallback image during page load (causing unnecessary overhead). Generally, it's a good idea to reference a small image here, as it's likely to be loaded in older/underpowered mobile devices.
* The `span[data-picture]` element's `alt` attribute is used as alternate text for the `img` element that picturefill generates upon a successful source match.
* The `span[data-picture]` element can contain any number of `span[data-source]` elements. The above example may contain more than the average situation may call for.
* Each `span[data-src]` element must have a `data-src` attribute specifying the image path.
* It's generally a good idea to include one source element with no `media` qualifier, so it'll apply everywhere - typically a mobile-optimized image is ideal here.
* Each `[data-src]` element can have an optional `[data-media]` attribute to make it apply in specific media settings. Both media types and queries can be used, like a native `media` attribute, but support for media _queries_ depends on the browser (unsupporting browsers fail silently).
* The `matchMedia` polyfill (included in the `/external` folder) is necessary to support the `data-media` attribute across browsers (such as IE9), even in browsers that support media queries, although it is becoming more widely supported in new browsers.
* The `noscript` element wraps the fallback image for non-JavaScript environments, and including this wrapper prevents browsers from fetching the fallback image during page load (causing unnecessary overhead). Generally, it's a good idea to reference a small mobile optimized image here, as it's likely to be loaded in older/underpowered mobile devices.

### HD Media Queries

Picturefill natively supports HD(Retina) image replacement. While numerous other solutions exist, picturefill has the added benefit of performance for the user in only getting served one image.
Picturefill natively supports HD(Retina) image replacement. While numerous other solutions exist, picturefill has the added benefit of performance for the user in only being served one image.

* The `data-media` attribute supports [compound media queries](https://developer.mozilla.org/en-US/docs/CSS/Media_queries), allowing for very specific behaviors to emerge. For example, a `data-media="(min-width: 400px) and (min-device-pixel-ratio: 2.0)` attribute can be used to serve a higher resolution version of the source instead of a standard definition image. Note you currently also need to add the `-webkit-min-device-pixel-ratio` prefix (e.g. for iOS devices).

```html
<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<div data-src="small.jpg"></div>
<div data-src="small.jpg" data-media="(min-device-pixel-ratio: 2.0)"></div>
<div data-src="medium.jpg" data-media="(min-width: 400px)"></div>
<div data-src="medium_x2.jpg" data-media="(min-width: 400px) and (min-device-pixel-ratio: 2.0)"></div>
<div data-src="large.jpg" data-media="(min-width: 800px)"></div>
<div data-src="large_x2.jpg" data-media="(min-width: 800px) and (min-device-pixel-ratio: 2.0)"></div>
<div data-src="extralarge.jpg" data-media="(min-width: 1000px)"></div>
<div data-src="extralarge_x2.jpg" data-media="(min-width: 1000px) and (min-device-pixel-ratio: 2.0)"></div>
<span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<span data-src="small.jpg"></span>
<span data-src="small.jpg" data-media="(min-device-pixel-ratio: 2.0)"></span>
<span data-src="medium.jpg" data-media="(min-width: 400px)"></span>
<span data-src="medium_x2.jpg" data-media="(min-width: 400px) and (min-device-pixel-ratio: 2.0)"></span>
<span data-src="large.jpg" data-media="(min-width: 800px)"></span>
<span data-src="large_x2.jpg" data-media="(min-width: 800px) and (min-device-pixel-ratio: 2.0)"></span>
<span data-src="extralarge.jpg" data-media="(min-width: 1000px)"></span>
<span data-src="extralarge_x2.jpg" data-media="(min-width: 1000px) and (min-device-pixel-ratio: 2.0)"></span>

<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<noscript>
<img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
</noscript>
</div>
</span>
```

* Note: Supporting this many breakpoints quickly adds size to the DOM and increases implementation and maintenance time, so use this technique sparingly.
Expand All @@ -78,19 +78,19 @@ Internet Explorer 8 and older have no support for CSS3 Media Queries, so in the
browsers, you might consider using conditional comments, like this:

```html
<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<div data-src="small.jpg"></div>
<div data-src="medium.jpg" data-media="(min-width: 400px)"></div>
<span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<span data-src="small.jpg"></span>
<span data-src="medium.jpg" data-media="(min-width: 400px)"></span>

<!--[if (lt IE 9) & (!IEMobile)]>
<div data-src="medium.jpg"></div>
<span data-src="medium.jpg"></span>
<![endif]-->

<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<noscript>
<img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
</noscript>
</div>
</span>
```

## Support
Expand Down
12 changes: 6 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ <h1>Picturefill: A &lt;picture&gt; element polyfill</h1>

<p>For more info: <a href="http://github.com/scottjehl/picturefill">see project home.</a></p>

<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<div data-src="external/imgs/small.jpg"></div>
<div data-src="external/imgs/medium.jpg" data-media="(min-width: 400px)"></div>
<div data-src="external/imgs/large.jpg" data-media="(min-width: 800px)"></div>
<div data-src="external/imgs/extralarge.jpg" data-media="(min-width: 1000px)"></div>
<span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<span data-src="external/imgs/small.jpg"></span>
<span data-src="external/imgs/medium.jpg" data-media="(min-width: 400px)"></span>
<span data-src="external/imgs/large.jpg" data-media="(min-width: 800px)"></span>
<span data-src="external/imgs/extralarge.jpg" data-media="(min-width: 1000px)"></span>

<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<noscript><img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript>
</div>
</span>
</body>
</html>
6 changes: 3 additions & 3 deletions picturefill.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*! Picturefill - Responsive Images that work today. (and mimic the proposed Picture element with divs). Author: Scott Jehl, Filament Group, 2012 | License: MIT/GPLv2 */
/*! Picturefill - Responsive Images that work today. (and mimic the proposed Picture element with span elements). Author: Scott Jehl, Filament Group, 2012 | License: MIT/GPLv2 */

(function( w ){

// Enable strict mode
"use strict";

w.picturefill = function() {
var ps = w.document.getElementsByTagName( "div" );
var ps = w.document.getElementsByTagName( "span" );

// Loop the pictures
for( var i = 0, il = ps.length; i < il; i++ ){
if( ps[ i ].getAttribute( "data-picture" ) !== null ){

var sources = ps[ i ].getElementsByTagName( "div" ),
var sources = ps[ i ].getElementsByTagName( "span" ),
matches = [];

// See if which sources match
Expand Down

0 comments on commit 2509318

Please sign in to comment.