[whatwg] img srcset / css image-set issues

Tab Atkins Jr. jackalmage at gmail.com
Wed Aug 22 09:19:30 PDT 2012

On Wed, Aug 22, 2012 at 4:22 AM, John Mellor <johnme at chromium.org> wrote:
> On Wednesday, August 22, 2012, Tab Atkins Jr. wrote:
>> I doubt this is actually what you want, though - you're probably not
>> actually trying to cater to devices with an 8:1 pixel ratio!  (Those
>> may not ever exist, even if technology does make it possible - I think
>> you drop below human perception about 5x or so.)
> This is nothing at all to do with 8:1 pixel ratios (though as a happy
> accident my proposal would also automatically scale to pixel ratios that
> aren't currently common). If you re-read my original email, you'll see that
> I defined "320x120, 320.jpg 1x, 640.jpg 2x, 1280.jpg 4x, 2560.jpg 8x" to
> mean that for each alternative image, the browser would multiply the
> provided intrinsic size (320x120) by that alternative's 'x' token to
> calculate the number of pixels of image data available in each dimension,
> then it would pick the one that most appropriately matches the number of
> device pixels the image is actually taking up in each dimension.
> So for example "1280.jpg 4x" means that this image is 4 times larger than
> the given intrinsic width of 320px. So sure, it would be suitable for
> display on a hypothetical 4x display at 320px width; but the browser also
> knows that it would be suitable for display on a 2x display at 640px width,
> a 1.5x display at 853px width, and a 1x display at 1280px width. The browser
> simply doesn't have that kind of information with the current srcset spec,
> so it is forced to be act more dumbly.
>> Let's assume that, instead, you're trying to serve two versions of the
>> image: one for small screens and one for larger screens, and each
>> version has two resolutions.  In that case, you'd do this:
>> <img style="width:100%" srcset="320.jpg 1x 320w, 640.jpg 2x 320w,
>> 1280.jpg 1x, 2560.jpg 2x">
> But that doesn't work! Let's look at some common devices for which it fails:
>     360w 2x portrait Galaxy S III => 2560.jpg instead of 640.jpg!
>     480w 1x landscape iPhone 3 => 1280.jpg instead of 640.jpg

The point of the w/h descriptors is to align with your media queries
to solve the "art direction" use-case, where different layouts may
demand images with different sizes/ratios which may be produced
differently (possibly generated from the same image, but with
different layouts or whatnot).

If one of your breakpoints was predicated on a "max-width: 320px" MQ,
then this is exactly what you want.  (This is probably not a great
breakpoint, since it's clearly focused on the iPhone and likely not
your content's actual breakpoint, but whatever.)

>     2560w 1x 30" desktop => 1280.jpg instead of 2560.jpg

This is adequate.  In the olden days before srcset, you'd just get the
1280 version all the time.  Now, if you'd like, you can toss in an
additional breakpoint with a "2560.jpg 2560w 1x" and be fine.  It's
not *perfectly ideal*, but it's fine.

The problem with trying to be smarter is that you have to be very
careful to not mess with the "art direction" use-case.  It's
*possible* to improve the syntax in the future to handle your last
example better, but it needs to be done with care.

>> Once again, using image-set() with MQ is *exactly* the same as the w
>> and h descriptors in <img srcset>.
>> We needed image-set() for resolution negotiation because you *can't*
>> use MQ for that.  Attempting to would have *horrible* usability, as I
>> explain in <http://www.xanthir.com/blog/b4Hv0>.  However, there's
>> nothing wrong with using MQ for width/height negotiation; after all,
>> that's their primary purpose.
> Ok, I understand where you're coming from on this point. It still seems a
> shame to have different syntax from srcset, and I feel one could justify
> making them the same by thinking of w/h in css as a shorthand even though it
> duplicates functionality. The benefits would include
> - Same syntax.
> - Avoid non-locality bugs due to paired image-sets being far apart in the
> CSS (changing one image, but forgetting to change the narrower/wider
> viewport one, etc).
> - Avoid browsers potentially downloading both assets (because typically the
> non-media-query one will be provided first, and some browsers might
> immediately start downloading it).
> - Easier to setup alternative images in a single .style.backgroundImage from
> JavaScript (can one even create media queries from JS?), so you don't have
> to rely on window resize event listeners.
> But perhaps these niggles are best solved with a more general way of doing
> inline media queries... is anything in the works?

I'm not actively working on anything right now, but my plan is to push
for @media to be nestable inside of style blocks, so you can put the
declarations right next to each other.


More information about the whatwg mailing list