├── .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 |
--------------------------------------------------------------------------------