├── .gitignore ├── README.md ├── bower.json ├── doc └── index.html ├── package.json ├── picturefill-background.js └── tests ├── index.html └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components 2 | /node_modules 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Picturefill-background 2 | A Responsive Images approach like Picturefill but managing a picture on background-image css attribute. 3 | 4 | **Note:** Picturefill-background works best in browsers that support CSS3 media queries.. 5 | 6 | ## Markup pattern and explanation 7 | 8 | Mark up your responsive images like this. 9 | 10 | ```html 11 |
12 | 13 | 14 | 15 | 16 |
17 | ``` 18 | 19 | ### Default options 20 | 21 | ```js 22 | w.picturefillBackgroundOptions = { 23 | selector: "picturefill-background", 24 | backgroundSize: "cover", 25 | backgroundRepeat: "no-repeat", 26 | backgroundPosition: "50% 50%" 27 | }; 28 | ``` 29 | 30 | Redefine this value to replace some of the options 31 | 32 | ```js 33 | picturefillBackgroundOptions.selector = "custom-selector"; 34 | ``` 35 | 36 | ### Explained... 37 | 38 | Notes on the markup above... 39 | 40 | * The `div[class="picturefill-background"]` element is used to apply `background-image` attribute. 41 | * The `div[class="picturefill-background"]` element can contain any number of `div[data-source]` elements. 42 | * Each `div[data-src]` element must have a `data-src` attribute specifying the image path. 43 | * Each `div[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 (unsupported browsers fail silently). 44 | * The [matchMedia](https://github.com/paulirish/matchMedia.js) polyfill is required to support the `data-media` attribute in older browsers (e.g. IE9, Android 2.3 Browser). See [http://caniuse.com/#feat=matchmedia](http://caniuse.com/#feat=matchmedia) for a table detailing native support for the `matchMedia` API. 45 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "picturefill-background", 3 | "version": "1.0.2", 4 | "license": "MIT", 5 | "keywords": [ 6 | "picture", 7 | "background", 8 | "responsive", 9 | "picturefill", 10 | "picturefill-background" 11 | ], 12 | "main": "./picturefill-background.js", 13 | "ignore": [ 14 | "index.html", 15 | "test.html", 16 | "test.js" 17 | ], 18 | "dependencies": {}, 19 | "devDependencies": { 20 | "matchmedia": "0.2.0", 21 | "mocha": "1.12.0", 22 | "chai": "1.7.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Picturefill-background 7 | 8 | 9 | 27 | 28 | 29 |
30 |
31 | 32 | 33 | 34 | 35 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "picturefill-background", 3 | "version": "1.0.3", 4 | "description": "A Responsive Images approach like Picturefill but managing a picture on background-image css attribute.", 5 | "main": "picturefill-background.js", 6 | "directories": { 7 | "doc": "doc", 8 | "test": "tests" 9 | }, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/M6Web/picturefill-background.git" 16 | }, 17 | "keywords": [ 18 | "picture", 19 | "background", 20 | "responsive", 21 | "picturefill", 22 | "picturefill-background" 23 | ], 24 | "author": "M6Web", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/M6Web/picturefill-background/issues" 28 | }, 29 | "homepage": "https://github.com/M6Web/picturefill-background#readme", 30 | "devDependencies": { 31 | "chai": "^1.7.2", 32 | "match-media": "0.2.0", 33 | "mocha": "^1.12.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /picturefill-background.js: -------------------------------------------------------------------------------- 1 | (function( w ) { 2 | "use strict"; 3 | 4 | /** 5 | * Utilities 6 | */ 7 | var escapeRegExp = function( string ) { 8 | return string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); 9 | }; 10 | 11 | /** 12 | * Default options 13 | * Redefine this value to replace some of the options 14 | * (ex: w.picturefillBackgroundOptions.selector = "custom";) 15 | */ 16 | w.picturefillBackgroundOptions = { 17 | selector: "picturefill-background", 18 | backgroundSize: "cover", 19 | backgroundRepeat: "no-repeat", 20 | backgroundPosition: "50% 50%" 21 | }; 22 | 23 | /** 24 | * Apply a responsive background image 25 | */ 26 | w.picturefillBackground = function() { 27 | var picturefills = w.document.getElementsByClassName( w.picturefillBackgroundOptions.selector ); 28 | 29 | for ( var i = 0, il = picturefills.length; i < il; i++ ) { 30 | var sources = picturefills[ i ].getElementsByTagName( "span" ), 31 | matches = []; 32 | 33 | for( var j = 0, jl = sources.length; j < jl; j++ ) { 34 | var src = sources[ j ].getAttribute( "data-src" ), 35 | media = sources[ j ].getAttribute( "data-media" ); 36 | 37 | if ( src && (!media || ( w.matchMedia && w.matchMedia( media ).matches )) ) { 38 | matches.push( src ); 39 | } 40 | } 41 | 42 | if ( matches.length ) { 43 | src = matches.pop(); 44 | var exp = new RegExp( escapeRegExp( src ) ); 45 | 46 | // Update target element's background image, if necessary 47 | if ( !exp.test( picturefills[ i ].style.backgroundImage ) ) { 48 | picturefills[i].style.backgroundImage = "url('" + src + "')"; 49 | picturefills[i].style.backgroundSize = w.picturefillBackgroundOptions.backgroundSize; 50 | picturefills[i].style.backgroundRepeat = w.picturefillBackgroundOptions.backgroundRepeat; 51 | picturefills[i].style.backgroundPosition = w.picturefillBackgroundOptions.backgroundPosition; 52 | } 53 | } 54 | } 55 | }; 56 | 57 | /** 58 | * Run on resize and domready (w.load as a fallback) 59 | */ 60 | if ( w.addEventListener ) { 61 | w.addEventListener( "load", w.picturefillBackground, false ); 62 | w.addEventListener( "resize", w.picturefillBackground, false ); 63 | w.addEventListener( "DOMContentLoaded", function() { 64 | w.picturefillBackground(); 65 | w.removeEventListener( "load", w.picturefillBackground, false ); 66 | }, false ); 67 | } 68 | else if ( w.attachEvent ) { 69 | w.attachEvent( "onload", w.picturefillBackground ); 70 | } 71 | 72 | }( window )); 73 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Picturefill-background 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | var assert = chai.assert, 2 | expect = chai.expect, 3 | should = chai.should(); 4 | 5 | var runTest = function () { 6 | describe('Default options', function() { 7 | it('default selector', function() { 8 | assert.equal(picturefillBackgroundOptions.selector, 'picturefill-background'); 9 | }); 10 | 11 | it('default background size', function() { 12 | assert.equal(picturefillBackgroundOptions.backgroundSize, 'cover'); 13 | }); 14 | 15 | it('default background position', function() { 16 | assert.equal(picturefillBackgroundOptions.backgroundPosition, '50% 50%'); 17 | }); 18 | 19 | it('default background repeat', function() { 20 | assert.equal(picturefillBackgroundOptions.backgroundRepeat, 'no-repeat'); 21 | }); 22 | }); 23 | 24 | describe('Override default options', function() { 25 | var options = picturefillBackgroundOptions; 26 | 27 | it('default selector', function() { 28 | picturefillBackgroundOptions.selector = "selector"; 29 | assert.equal(picturefillBackgroundOptions.selector, 'selector'); 30 | }); 31 | 32 | it('default background size', function() { 33 | picturefillBackgroundOptions.backgroundSize = "size"; 34 | assert.equal(picturefillBackgroundOptions.backgroundSize, 'size'); 35 | }); 36 | 37 | it('default background position', function() { 38 | picturefillBackgroundOptions.backgroundPosition = "position"; 39 | assert.equal(picturefillBackgroundOptions.backgroundPosition, 'position'); 40 | }); 41 | 42 | it('default background repeat', function() { 43 | picturefillBackgroundOptions.backgroundRepeat = "repeat"; 44 | assert.equal(picturefillBackgroundOptions.backgroundRepeat, 'repeat'); 45 | }); 46 | 47 | picturefillBackgroundOptions = options; 48 | }); 49 | 50 | describe('Current background picture', function() { 51 | var viewportWidth = document.documentElement.clientWidth; 52 | var container = document.getElementsByClassName( picturefillBackgroundOptions.selector ); 53 | var picture = container[0].style.backgroundImage; 54 | 55 | var type = "big"; 56 | 57 | if (viewportWidth < 400) { 58 | type = "small"; 59 | } 60 | else if (viewportWidth < 640) { 61 | type = "medium"; 62 | } 63 | else if (viewportWidth < 800) { 64 | type = "large"; 65 | } 66 | 67 | it(type + " background", function() { 68 | assert.equal(picture, "url(http:\/\/" + type + "\/)"); 69 | }); 70 | }); 71 | 72 | mocha.run(); 73 | }; 74 | 75 | --------------------------------------------------------------------------------