While picturefill are full functional responsive images polyfills, the lazySizes respimg polyfill extension is only a partial polyfill, which supports only the most important subset of the native responsive images standard and only in conjunction with the lazySizes core script.
As a result it is an extreme fast and lightweight plugin.
// never try to import *.min.js files
import lazySizes from 'lazysizes';
import 'lazysizes/plugins/respimg/ls.respimg';
This plugin supports both art directed responsive images using the picture
element as also resolution switching based on data-srcset
using the width descriptor (and of course the combination of both).
- The use of explicit density descriptors (x descriptor) are not supported (This should not be a problem, because all use cases of the density descriptor can always also be substituted with a width descriptor).
- If
data-srcset
with width descriptors (w descriptor) are used either thedata-sizes="auto"
feature has to be used or thesizes
value has to consist of just one source size value with the CSS px unit. - If picture is used the
img
element should not have asrcset
/data-srcset
attribute, instead the lastsource
element should/can be used without amedia
andtype
attribute. - The use of the
source[type]
attribute is not automatically supported, but can be manually added by overriding thelazySizesConfig.supportsType
option callback function. - The use of the
source[media]
is supported for all browsers, which do supportmatchMedia
. To add full support for IE9 and other legacy browsers awindow.matchMedia
polyfill orModernizr.mq
(Modernizr Media Queries) can be used.
Aside from above mentioned constraints everything else is fully supported. Here are some practical examples of fully supported responsive images:
<script>
window.lazySizesConfig = window.lazySizesConfig || {};
//in case you want to use custom media query aliases in your markup, instead of full media queries
window.lazySizesConfig.customMedia = {
'--small': '(max-width: 480px)',
'--medium': '(max-width: 700px)',
'--large': '(max-width: 1400px)'
};
</script>
<!-- use of width descriptor + data-sizes="auto" -->
<img
data-sizes="auto"
data-srcset="image1.jpg 300w,
image2.jpg 600w,
image3.jpg 900w" class="lazyload" />
<!-- picture with one implicit density descriptor per srcset -->
<picture>
<!--[if IE 9]><audio><![endif]-->
<source
data-srcset="http://placehold.it/500x600/11e87f/fff"
media="--small" />
<source
data-srcset="http://placehold.it/700x300"
media="--medium" />
<source
data-srcset="http://placehold.it/1400x600/e8117f/fff"
media="--large" />
<source
data-srcset="http://placehold.it/1800x900/117fe8/fff" />
<!--[if IE 9]></audio><![endif]-->
<img
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
class="lazyload"
alt="image with artdirection" />
</picture>
<!-- picture with explicit w descriptors and data-sizes="auto" -->
<picture>
<!--[if IE 9]><audio><![endif]-->
<source
data-srcset="http://placehold.it/500x600/11e87f/fff 500w,
http://placehold.it/750x900/11e87f/fff 750w"
media="--small" />
<source
data-srcset="http://placehold.it/700x300 700w,
http://placehold.it/1050x450 1050w"
media="--medium" />
<source
data-srcset="http://placehold.it/1400x600/e8117f/fff 1400w,
http://placehold.it/2100x900/e8117f/fff 2100w"
media="--large" />
<source
data-srcset="http://placehold.it/1800x900/117fe8/fff 1800w,
http://placehold.it/2700x1350/117fe8/fff 2700w" />
<!--[if IE 9]></audio><![endif]-->
<img
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
class="lazyload"
data-sizes="auto"
alt="image with artdirection" />
</picture>
<!-- use of width descriptors + simple sizes value with px unit -->
<img
data-srcset="image1.jpg 300w,
image3.jpg 600w"
sizes="300px"
class="lazyload" />
As explained above this partial polyfill only accepts one value for sizes
using only the px length. Due to the fact, that also data-sizes="auto"
is supported the lazybeforesizes
event can be used to dynamically change/add different sizes
:
document.addEventListener('lazybeforesizes', function(e){
//calculate the size as a number
e.detail.width = yourCalculation(e.target) || e.detail.width;
});