Why HTML5 image srcset loads two images at the same time? - html

I've got a problem with uderstanding why html5 img attribute doesn't work corectly?
In this chunk I set srcset, and when I have screen width 320px, i gonna get image-xs.jpg, but browser shows image-md.jpg and I think it because of loads to images. Is it a bug or I don't understand something? Explain please and won't tell about tag picture and img inside, I wonder, why specifically img works so?
<img
sizes="(min-width: 700px) 80vw, 100vw"
srcset="img/image-xs.jpg 375w,
img/image-sm.jpg 480w,
img/image-md.jpg 768w"
alt="City">

Related

How to use image srcset properly in HTML5

I have setup the following img srcset:
<img srcset="http://via.placeholder.com/320x150 320w,
http://via.placeholder.com/480x150 480w,
http://via.placeholder.com/800x150 800w"
src="http://via.placeholder.com/800x150"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
width="200" />
No matter how I set the width of the img, or how I resize the window, chrome always downloads and displays the 800px wide image. What gives? Adding sizes attribute also has no effect. I referenced this article.
Demo here: http://jsfiddle.net/7ek62m13/1/
You are using srcset the correct way. Srcset is for when you have big images and you have smaller formats on smaller devices. If you load the biggest image there is no need to load another smaller image (cause a srcset is meant for the same image). This results in when you open this code on your phone it will display the smallest image, but when you are on desktop it will open the regular image. If you upscale your browser again srcset will replace your image with a bigger image but it will never swap back to a lower image. I hope I made it a bit clearer.

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">

Can anyone see where I'm going wrong with this srcset?

I'm building a responsive Wordpress website. The blog feed has a list of stories which have a title and an image. The image sizes should be as follows:
up to 479px wide - 140x140px (stories are displayed in a list)
over 480px wide - 360x190px (stories are displayed in a row of 3)
I've been trying to use SRCSET for this so that the 140x140px image would be loaded for browsers up to 479px and the 360px image would be loaded for browsers 480px and over.
I've googled and read literally every bit of documentation out there on sizes and srcset but I just can't get my head around it. So far I've come up with the following:
<img
src="http://placekitten.com/140/140"
srcset="
http://placekitten.com/140/140 140w,
http://placekitten.com/360/190 360w"
sizes="
(max-width: 479px) 140px,
(min-width: 480px) 360px,
100vw"
alt=""
class="lazyload"
/>
Unfortunately all this does is display the 360x190px at every width, despite the actual src of the image being set to the 140x140px image.
Can anyone see what I've missed? I think it's the sizes that I'm most confused about. I added in media queries like documented but they don't seem to be applied?
Thank you!
Note that this srcset strategy on the <img> element depends on the fact that the browser has not cached the image yet. This strategy is meant to save the bandwidth for the browser. So, if you start off with a wide viewport, the browser simply fetches the larger of the two images and will no longer fallback to the smaller one even if you resize.
If you want to force the browser to load images at various viewport breakpoints, use <picture> instead:
<picture alt="" class="lazyload">
<source srcset="https://via.placeholder.com/360x190" media="(min-width: 480px)" />
<img src="https://via.placeholder.com/140x140" />
</picture>
Check out the code below.
<picture>
<source class="img-fluid" srcset="//www.fillmurray.com/140/140" media="(max-width: 479px)"><img class="img-fluid" src="//www.fillmurray.com/360/190">
</picture>

img srcset doesn't work

Can't seem to get this to work. Currently only the full-size img (soho-w920h665) loads.
What I'm trying to do: the img spans 100vw until window width is 766px or bigger, then the img spans only 50vw.
<img
srcset="/img/soho-w500h361.jpg 500,
/img/soho-w700h605.jpg 700,
/img/soho-w920h665.jpg 920"
sizes="(min-width : 766px) 50vw,
data-src="/img/soho-w920h665.jpg
">
Make sure you're using the right syntax for it, src attribute seems to be missing for now. An example of correct syntax would be -
<img src="clock-demo-thumb-200.png"
alt="Clock"
srcset="clock-demo-thumb-200.png 200w,
clock-demo-thumb-400.png 400w"
sizes="(min-width: 600px) 200px, 50vw">
so double check your data-src attribute. Look into MDN documentation for better insight here - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img

How do I tell srcset attribute to load NO images when viewport smaller than certain size

I'm having trouble understanding how to keep srcset from loading any images on screens < 768px.
I've tried the code below but the sizes attribute doesn't seem to do what you may think.
Below loads 1024.jpg on all screen sizes:
<img
src="default.jpg"
srcset="img/1024.jpg 1024w"
sizes="(min-width: 768px) 768px, 100vw"
/>
Or the picture element, if it would honor an empty srcset but it only "hints" to which image a browser should load.
The other answer isn't really satisfying. In general with srcset you give the browser the choice to select an image candidate. While you can assume which image is taken on certain devices. You don't have any control. Each image in srcset can be taken.
So if you want to control, what is used or not used, you need to use the picture element.
Here are 3 examples. If the viewport is 768px or wider the 'img/1024.jpg' image is downloaded, otherwise a data uri or a broken img is selected.
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source srcset="img/1024.jpg" media="(min-width: 768px)">
<!--[if IE 9]></video><![endif]-->
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Image">
</picture>
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" media="(max-width: 768px)">
<!--[if IE 9]></video><![endif]-->
<img src="img/1024.jpg" alt="Image">
</picture>
<!-- you can also write (but this makes it invalid) -->
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source srcset="img/1024.jpg" media="(min-width: 768px)">
<!--[if IE 9]></video><![endif]-->
<img alt="Image">
</picture>
Although the first and the second code example are absolutely valid. There is currently some discussion to allow this by simply omitting the srcset (see code example 2). See this discussion here: https://github.com/ResponsiveImagesCG/picture-element/issues/243
There's a really simple solution to this which works without <picture>.
It is likely not intended to be used this way, but it works very well.
Attach a 1x1px image and it will be used whenever sizes == 0vw. In this case this would be true for everything under 768px:
<img
src="default.jpg"
srcset="img/null.jpg 1w
img/1024.jpg 1024w"
sizes="(max-width: 768px) 0vw, 100vw"
/>
I'm aware that this is not answering the OP's question of "loading NO images", but it's relatively close and you can reference the same 1x1 px image in all other situations, which means it's not gonna be downloaded there.
One caveat:
In the following situation I believe the browser might decide to use the 1x1px image already from 512px and downwards even though we specify 100px
<img
src="default.jpg"
srcset="img/null.jpg 1w
img/1024.jpg 1024w"
sizes="(max-width: 100px) 0vw, 100vw"
/>
This is due to the fact that the browser takes whatever is closest to the desired size in this case 1 is closer to 511 than 1024 is... not sure though
Edit: This situation could quite easily be fixed by attaching a 200w image as well, which you would likely do in any case
EDIT:
To say it simply, you can't.
Removing/hiding an image element must be done in CSS with media queries, or with Javascript.
The srcset and sizes tags are useful for choosing the content source of an image element, but it cannot control the existence or visibility of the element.
The srcset and sizes tags are intended to augment responsive CSS. Their values should follow whatever breakpoints are defined in CSS.
srcset
srcset is a list of available images the browser can choose from with their respective widths.
According to the latest spec, it will choose only from that list when populated:
For backwards compatibility, one of the URLs is specified in the img element's src attribute. In new user agents, the src attribute is ignored when the srcset attribute uses w descriptors.
Therefore, it sees 1024.jpg as the only choice and ignores default.jpg.
Add the default image to srcset (with the correct w descriptor - here I assume default.jpg is 768px wide):
<img
src="default.jpg"
srcset="default.jpg 768w, img/1024.jpg 1024w"
sizes="(min-width: 768px) 768px, 100vw"
/>
sizes
sizes tells the browser how wide the image will be when a given media query is true. This helps the browser calculate which image to pick from srcset.
Currently, sizes="(min-width: 768px) 768px, 100vw" is telling the browser:
"The image will be 768px wide if the viewport is larger than 768px, otherwise the image will be full width when the viewport is less than 768px."
I assume you don't want to use a 1024px image when the viewport is less than 768px.
To hint at a small image when the viewport is less than 768px, use max-width: 768px instead:
<img
src="default.jpg"
srcset="default.jpg 768w, img/1024.jpg 1024w"
sizes="(max-width: 768px) 768px, 100vw"
/>