Specifying image for pixel density with srcset and sizes - html

I am trying to get to grips with srcset but I am having trouble finding a detailed reference.
From what I understand I can do something like this to specify an image for a mobile phone.
<img src="1.jpg" alt=""
srcset="1x300.jpg 300w"
sizes="(max-width: 480px) 300px">
However I am unclear how I can specify to correct image for the display density.
In the above example at a screen width of less than 480px I have specified to use the 300px image. However on a 2x retina display I would want a 600px width image but the screen size will still read as 480px.
How do I specify another image for a different pixel density?

Basic structure for the IMG tag with SRCSET and SIZES,
<img src="images.jpg" srcset="images1x.jpg 200w, images2x.jpg 400w,
images8x.jpg 600w" sizes="(max-width: 40em) 100vw, 50vw" alt="Some Text">
Reference

Related

HTML picture element downloading wrong image on mobile

I'm running a page through Google's Page Speed Analyzer and for mobile, it's telling me I should download the proper size images. I know the viewport size, but I don't know the width of the slot because we are using a responsive layout. I've looked at the documentation and a bunch of examples and none of them are using what I think should be the correct image.
The Network tab of developer tools is showing we are downloading about.webp for mobile and not either of the smaller images (200px or 400px). Even when changing the device in Chrome to a smaller viewport width, it still downloads about.webp.
What is the correct HTML for a picture element to get Page Speed Analyzer to use the appropriate image?
Below is my picture element. Thanks!
<div class="row"><div class="col-md-3">
<picture>
<source type="image/webp"
sizes="(max-width: 200px) 200px,
(max-width: 400px) 400px,
(max-width: 1500px) 1500px"
srcset="//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w200.webp 200w,
//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w400.webp 400w,
//cdn.storyboardthat.com/site-images/articles/education/about-sbt.webp 1500w">
<source type="image/png"
sizes="(max-width: 200px) 200px,
(max-width: 400px) 400px,
(max-width: 1500px) 1500px"
srcset="//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w200.png 200w,
//cdn.storyboardthat.com/site-images/articles/education/about-sbt-w400.png 400w,
//cdn.storyboardthat.com/site-images/articles/education/about-sbt.png 1500w">
<img src="//cdn.storyboardthat.com/site-images/articles/education/about-sbt.png"
alt="Storyboard That"
title="Storyboard That"
class="lazyload "
style="max-width:100%;height:auto;"
width="1500" height="400" loading="lazy">
</picture>
</div>
You have forgotten about Device Pixel Ratio (DPR).
You see the <picture> element basically says to browsers "here are a few options to choose from, I have indicated my preference but it is up to you to decide which image you think is best".
As you haven't specified a DPR preference the browser is using the following logic:
"Ok so I have 3 images to choose from, what is my current DPR? Oh I have DPR set to 3.
How big is the image at this screen width (320px)? Full screen width so I need a 320px image.
Ok so it is 320px * 3 DPR to ensure I have the highest quality image that matches my current display resolution.
So I need a 960px image minimum. My options are 200, 400 or 1500, I better choose the 1500 image and down sample it."
So how do I control pixel density decisions?
You can specify pixel density with 1x, 2x, 4x etc. For example:
<img src="default.webp"
srcset="hiddef.webp 2x, heighestdef.webp 4x"
alt="Image description">
However with how you have currently structured your picture element it won't quite work as you can't combine image 200w with image 2x to do image 200w 2x.
If you want to keep the same image at all DPIs then you would specify that image 3 times.
<img src="default.webp"
srcset="default.webp 2x, default.webp 4x"
alt="Image description">
Otherwise if you want the browser to change the image automatically based on DPR just leave your <picture> element as it is.
I see that the code snippet you have used is incorrect, refer this:
<picture>
<source media="(max-width:200px)" srcset="about-w200.webp">
<source media="(max-width:400px)" srcset="about-w400.webp">
<img src="about-sbt.webp alt="About" style="width:auto;">
</picture>
A working reference link

HTML img srcset not behaving as intended?

I am trying to load responsive images and things seem to be working in the latest version of firefox. However, my images are not loading as intended in Safari and Chrome.
<img
src="/images/pages/arrivals/02_exterior_1000.jpg"
srcset="/images/pages/arrivals/02_exterior_400.jpg 400w,
/images/pages/arrivals/02_exterior_600.jpg 600w,
/images/pages/arrivals/02_exterior_800.jpg 800w,
/images/pages/arrivals/02_exterior_1000.jpg 1000w"
alt="Blank"
/>
The goal is to have each of these images load on their respective screen. 02_exterior_400.jpg should load on screens less than 400px. 02_exterior_600.jpg loads on screens less than 600px, etc. Each of these images should be taking up 100vw.
On Chrome (see below) my page is at 386px but it's loading the 800px image and I want it to load the 400px:
Same issue on Safari. What am I doing incorrectly?
Edit: Chrome/Safari seem to be doubling my screen width when deciding which image to load. For example: if my screen is at 350px the browser is interpreting it at as 700px and then loading 02_exterior_800.jpg.
Any help appreciated,
thanks
You may be missing the "sizes" attribute. Also, put the regular "src" attribute after the "srcset" attribute. This is used as a fallback if the first srcset is either not supported, or the images are not found.
<img srcset="/images/pages/arrivals/02_exterior_400.jpg 400w,
/images/pages/arrivals/02_exterior_600.jpg 600w,
/images/pages/arrivals/02_exterior_800.jpg 800w,
/images/pages/arrivals/02_exterior_1000.jpg 1000w"
sizes="(max-width: 400px) 400px,
(max-width: 600px) 600px,
(max-width: 800px) 800px,
1000px"
src="/images/pages/arrivals/02_exterior_1000.jpg" alt="A Sense of Arrival">

Responsive images using srcset/sizes isn't respected by Safari iOS

I have the following
<img
src="/img/footer/logo_white.png?v=2.0"
srcset="/img/footer/logo_white.png?v=2.0 1x,
/img/footer/logo_white2x.png?v=2.0 2x"
>
which works fine on normal and hiDPI screens.
But when the viewport's very small (below 400px) the logo doesn't fit therefore I need a smaller version of the image in terms of real length, which I created. Then I tried
<img
class="biw-logo"
sizes="(max-width: 390px) 110px, 175px"
src="/img/footer/biw_logo.png?v=2.0"
srcset="/img/footer/biw_logo_small.png?v=2.0 110w,
/img/footer/biw_logo.png?v=2.0 175w,
/img/footer/biw_logo2x.png?v=2.0 350w"
>
Which works in terms of showing the _small image for viewports lower than 390 pixels - but now I've lost the "high resolution" factor; I cannot force the iOS browser in iphone5s to display a 220px image in length of 110px with the above syntax.
Could you correct my syntax?
<img class="biw-logo" sizes="(max-width: 390px) 110px, 175px" src="http://placehold.it/175x75" srcset="http://placehold.it/110x50 110w,
http://placehold.it/175x75 175w, http://placehold.it/350x150 350w">
You can do that with srcset and sizes. At first tell the browser which images you have available and how many pixels wide these images are, this can be done with srcset:
<img srcset="
/img/footer/logo_white.png?v=2.0 300w,
/img/footer/logo_white2x.png?v=2.0 600w,
/img/footer/logo_white_small.png?v=2.0 150w
">
Now the browser knows it can select from three images that are 150, 300 and 600 pixels wide (I guessed the dimensions, your actual widths might be different).
Second, you tell the browser how large the image will be displayed in the webpage, this can be achieved with sizes:
<img
sizes="(max-width: 400px) 150px, 300px"
srcset="..."
>
The browser knows now, that if the width of the viewport is 400px or less the image will be displayed 150px wide, for viewports larger than 400px it is displayed 300px wide.
This is enough information for the browser to select the right image. On a normal desktop with a normal screen it will select the 300w-image and on a HiDPI desktop it will be the 600w one. On a small viewport with a normal screen the 150w will get selected and on a small viewport with HiDPI the 300w one.
If you want more information about srcset and sizes, take a look at http://ericportis.com/posts/2014/srcset-sizes/.
You also can try using a couple more sources like that:
<picture>
<source srcset="img.png" media="(resolution: 150dpi)" type="image/png" />
<source srcset="img2x.png" media="(resolution: 300dpi)" type="image/png" />
<img src="img.png" alt="alt text" />
</picture>
Or something like that - i didn't test it, i need to learn more about resolution media query to be sure.

img srcset and sizes not working as I would expect

I am currently trying to make better responsive images on my site. After some research I found the the srcset and sizes attributes.
My goal here is the following:
When the screen size is above 600px or below 300px I want to serve a 250x250 image
When it is between these two values I want to serve a 350x350 image
Also I want higher resolution images for screens which have a higher pixel ratio
This is what I came up with. But it is not working as I though it would. The small 250x250 is always being served.
<img src="https://placehold.it/250"
srcset="https://placehold.it/700 700w, https://placehold.it/500 500w, https://placehold.it/350 350w, https://placehold.it/250 250w"
sizes="((max-width: 600px) and (min-width: 300px) and (min-resolution: 2)) 350px, (min-resolution: 2) 250px, ((max-width: 600px) and (min-width: 300px)) 350px, 250px" />
And I have one additional question:
In my tests I found out that the browser won't load new images when the window is resized so that a different image should be served. Is it possible to do that?
Ok. After some tidious research I found out that I did not understand the sizes-attribute correctly.
The following is how I can achieve what I want:
<img src="https://placehold.it/250"
srcset="https://placehold.it/700 700w, https://placehold.it/500 500w, https://placehold.it/350 350w, https://placehold.it/250 250w"
sizes="(max-width: 600px) calc(100vw - 50px), 250px" />

img srcset - disregard pixel density

I have two images, one is 1000 x 800 px ("large"), and one is 200 x 200 px ("small").
I want to use srcset / sizes / picturefill to display the small image when the screen is less than or equal to 500 CSS pixels wide, and the large image otherwise.
Here's a straw-man proposal: http://jsfiddle.net/ghhjfo4z/1/embedded/result/
<img srcset="http://i.imgur.com/hw9O9Ia.jpg 1000w, http://i.imgur.com/BgLoqRx.jpg 500w">
This works fine on my 1x pixel density display. But when I switch over to my 2x pixel density retina display, suddenly the small image is only displayed when the viewport is less than or equal to 250 CSS pixels wide.
Is there any way to make the browser use the small image on my 2x pixel density display when the viewport is less than or equal to 500px?
Basically I want to disregard the pixel density of the device, and use srcset and/or sizes to only choose an image based on CSS pixel width of a viewport.
Just for completion: I found the following solution working for me:
<img
srcset="http://i.imgur.com/hw9O9Ia.jpg 1000w,
http://i.imgur.com/BgLoqRx.jpg 500w"
sizes="(-webkit-min-device-pixel-ratio: 2) 50vw,
(min-resolution: 192dpi) 50vw,
(min-resolution: 2dppx) 50vw,
(-webkit-min-device-pixel-ratio: 3) 33.33vw,
(min-resolution: 288dpi) 33.33vw,
(min-resolution: 3dppx) 33.33vw" />
In short this is not possible. If you want to have more control you can use the picture element.
<picture>
<source srcset="img-500w.jpg" media="(max-width: 650px)" />
<img srcset="img-1000w.jpg" />
</picture>
There is also an interesting lazySizes plugin for you, optimumx. Markup would look like this:
<img
data-srcset="http://placehold.it/300x150 300w,
http://placehold.it/700x300 700w,
http://placehold.it/1400x600 1400w,
http://placehold.it/2800x1200 2800w"
data-sizes="auto"
data-optimumx="1.5"
class="lazyload"
src="http://placehold.it/300x150"
alt="flexible image" />
It would be wise to set it to 1.2 or better 1.5 instead of just 1.
For other performance vs. retina considerations have a look here.