-
Notifications
You must be signed in to change notification settings - Fork 37
The picture element vs the img srcset solution
This page needs to compare both solutions objectively. It must show if either solution does not meet a particular use case.
-
rwldrn's comparison of
picture
andimg@srcset
from API perspective - particularly, it shows how hard it would be to work withsrcset
. Clearly, srcset needs something likeDOMTokenList
.
The above is copied here.
Given the following:
<picture id="ui-picture" alt="">
<source src="large.jpg" srcset="large.jpg 1x, large-high.jpg 2x" media="min-width: 600px">
</picture>
<img id="ui-img" src="large.jpg" alt="" srcset="large-high.jpg 2x">
Q: How do I add a "mobile" image?
A: (with <picture>
)
var source = document.createElement("source");
source.src = "mobile.jpg";
source.srcset = "low.jpg 0.5x, mobile.jpg 1x, mobile-hd.jpg 2x";
document.getElementById("ui-picture").appendChild(source);
A: (with <img>
)
var img = document.getElementById("ui-img");
img.srcset += ", low.jpg 600w 0.5x, mobile.jpg 600w 1x, mobile-hd.jpg 600w 2x";
This is assuming that there wasn't a trailing comma in the original srcset attribute.
Q. How do I remove an image?
A: (with <picture>
)
var source = document.querySelector("#ui-picture [src='mobile.jpg']");
source.parentNode.removeChild(source);
A: (with <img>
)
var img = document.getElementById("ui-img");
// since there is no consensus on an API for this, I'm forced to roll my own...
var sources = img.srcset.split(",");
var removes = [
"low.jpg 600w 0.5x",
"mobile.jpg 600w 1x",
"mobile-hd.jpg 600w 2x"
];
img.srcset = sources.filter(function( val ) {
if ( removes.indexOf(val.trim()) === -1 ) {
return true;
}
}).join(", ");
For those of you following at home, these are just new examples of old DOM pain points with different words. Neither is very good, but at least picture+source is familiar DOM node creation, removal territory. img+srcset is a trip down memory lane with class attributes. Neither example is capable of sparing the developer from pain if they want to remove a single entry from a source.srcset or img.srcset; picture+source makes it less awful by making the values potentially addressable via query apis.
Of course, most web developers will prefer to use a library like jQuery (http://trends.builtwith.com/javascript/jQuery), because standards have betrayed everyone by making the simplest tasks verbose, awkward and painful to use (I'm talking about the physical pain one endures from typing obscenely long API names).
Let's look at the examples above through the eyes of the average web developer using jQuery:
Q: How do I add a "mobile" image?
A: (with <picture>
)
$("#ui-picture").append(
"<source src='mobile.jpg' srcset='low.jpg 0.5x, mobile.jpg 1x, mobile-hd.jpg 2x'>"
);
A: (with <img>
)
// we can only hope that the dev is smart enough to cache the selection...
var img = $("#ui-img");
img.attr({
srcset: img.attr("srcset") + ", low.jpg 600w 0.5x, mobile.jpg 600w 1x, mobile-hd.jpg 600w 2x"
});
Again, this is assuming that there wasn't a trailing comma in the original srcset attribute.
Q. How do I remove that same "mobile" image?
A: (with <picture>
)
$("#ui-picture [src='mobile.jpg']").remove();
A: (with <img>
)
var removes = [
"low.jpg 600w 0.5x",
"mobile.jpg 600w 1x",
"mobile-hd.jpg 600w 2x"
];
$("#ui-img").attr("srcset", function( i, sources ) {
return sources.split(",").filter(function( val ) {
if ( removes.indexOf(val.trim()) === -1 ) {
return true;
}
}).join(", ");
});
Less horrible, but still completely convoluted.
None of the above addresses the issue that srcset is still a string with multiple comma separated values—that's an issue for another day.