Picture source with srcset - html

I want to use tag and 3 image formats. avif \ webp \ png. At the same time, but not to forget about retina displays.
At the moment I came up with something like this format:
<picture>
<source srcset="components/header/img/logo.avif, components/header/img/logo#2x.avif 2x" type="image/avif">
<source srcset="components/header/img/logo.webp, components/header/img/logo#2x.webp 2x" type="image/webp">
<img class="someClass" src="components/header/img/logo.png" srcset="components/header/img/logo#2x.png 2x" alt="Logo">
</picture>
But how much of this is correct ? Maybe it should be implemented in some other way ?

You can combine both concepts via an art-direction rule.
The art direction concept is basically intended to switch between different image versions with different aspect ratios depending on your viewport size.
Example from german web studio "kulturbanause":
<picture>
<source media="(min-width: 56.25em)" srcset="large.webp" type="image/webp">
<source media="(min-width: 56.25em)" srcset="large.jpg">
<source media="(min-width: 37.5em)" srcset="medium.webp" type="image/webp">
<source media="(min-width: 37.5em)" srcset="medium.jpg">
<source srcset="small.webp" type="image/webp">
<source srcset="small.jpg">
<img src="fallback.jpg" alt="">
</picture>
Use svg if feasible (logos, info graphics etc)
Referring to your code example referencing a logo img:
Most likely, your logo could be used as a svg.
If it's created (or optimized) well, you don't need any HiRes candidates.
(and most likely svg will also wipe the floor with raster images regarding filesize)
See also: MDN Docs: Responsive images

While the standard HTML <img> element doesn't support compatibility fallbacks for images, the <picture> element does. <picture> is used as a wrapper for a number of <source> elements, each specifying a version of the image in a different format or under different media conditions, as well as an <img> element which defines where to display the image and the fallback to the default or "most compatible" version.
<picture>
<source srcset="diagram.svg" type="image/svg+xml">
<source srcset="diagram.png" type="image/png">
<img src="diagram.gif" width="620" height="540"
alt="Diagram showing the data channels">
</picture>
More info developer.mozilla.org
I hope I was helpful

In the end I got a design that works with both image switching to source (we can get avif\webp for browsers that support it) and srcset which allows us to output x1 or x2 images for different displays.
path to files only for example :)
<picture>
<source srcset="components/features/img/icon-5.avif 1x, components/features/img/icon-5#2x.avif 2x" type="image/avif">
<source srcset="components/features/img/icon-5.webp 1x, components/features/img/icon-5#2x.webp 2x" type="image/webp">
<img class="someClass" src="components/features/img/icon-5.png" alt="Icon" srcset="components/features/img/icon-5.png 1x, components/features/img/icon-5#2x.png 2x">
</picture>

Related

Is a 2nd <source> tag required for image fallback in HTML?

What is the proper way to do, for example, a WebP fallback to JPG inside an HTML <picture> tag?
Is it this (as in this StackOverflow answer https://stackoverflow.com/a/39338181):
<picture>
<source type="image/webp" srcset="image.webp">
<img src="image.jpg">
</picture>
-- or (as shown on css-tricks https://css-tricks.com/using-webp-images/#using-webp-in-html) --
<picture>
<source type="image/webp" srcset="image.webp">
<source type="image/jpeg" srcset="image.jpg">
<img src="image.jpg">
</picture>
All I can find is conflicting information...

Can loading="lazy" be used on <source>

I know I can use loading="lazy"on <img> and <iframe> for browser native lazy loading, but can I also use this attribute on <source>? I cannot find related documentation.
Something like this:
<picture>
<source srcset="/image.webp" type="image/webp" loading="lazy"/>
</picture>
No, it can't be used on source, because a <picture> element has to have one <img> element inside. This <img> can have the lazy attribute. The browser then figures out on his own (at least I hope it does) which of the source tags it should lazy-load.
Description of picture from MDN
The HTML element contains zero or more <source> elements and one <img> element to offer alternative versions of an image for different display/device scenarios.
So the correct code to lazy-load a source should be:
<picture>
<source srcset="/media/examples/surfer-240-200.jpg"
media="(min-width: 800px)">
<img src="/media/examples/painted-hand-298-332.jpg" alt="" loading="lazy"/>
</picture>
Cloned was correct - if using picture to wrap around sources, the last element should be a fallback img tag. The browser uses the img 'alt' and the 'loading="lazy" to feed into these sources.
Example, if any of these images are fetched, they'll be done so in a lazy manner:
<picture>
<source media="(min-width: 0)" srcset="image/bike-480.jpg">
<source media="(min-width: 800px)" srcset="image/bike-900.jpg">
<source media="(min-width: 1200px)" srcset="image/bike-1300.jpg">
<img loading="lazy" src="image/mage/bike-900.jpg" alt="man riding a blue bicycle">
</picture>

HTML picture element not working in Edge or Firefox

This is the sort of thing I'm doing:
<picture style="display: block; margin:auto;">
<source media="(min-width: 1080px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-1080.webp">
<source media="(min-width: 600px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-720.webp">
<source media="(min-width: 360px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-360.webp">
<!-- ios media -->
<source media="(min-width: 1024px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-1080.jpp">
<source media="(min-width: 750px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-750.jpp">
<source media="(min-width: 640px)" srcset="imagesIndex\hero-images\centaurs-horn-crop-640.jpg">
<img src="imagesIndex\hero-images\centaurs-horn-crop-750.jpg" alt="Firenze, Harry Potter's divination teacher poses for a photo for my walking tour on Edinburgh's Royal Mile" class="center-box"/>
</picture>
Wrapped in <picture> tags. And it does not work, not even the fallbacks work. Is there a work around? Do I need to cut the alt text or something? What can I do?
It's meant to work on both. And the fallback is always meant to work (actually does in IE) so why doesn't it here?
It's a graphics rich site viewed on mobile, I need to use Webp whenever possible.
Site is here
www.pottertour.co.uk/index.html
I see a possible problem because of the file extensions on the later .jpg images, a couple of them are marked as jpp instead of jpg.

HTML5 Picture element does not seem to be supported by Chrome 52? Srcset not working

I just started a new webpage so there's not much markup to go over.
I set this down:
<picture>
<source media="(min-width: 1000px)"
srcset="images/largeme.jpg">
<source media="(min-width: 465px)"
srcset="images/medme.jpg">
<img src="images/smallme.jpg"alt="hero profile">
</picture>
and it defaults to the medme.jpg picture no matter the width of the window. I set down this:
<picture>
<source media="(min-width: 1000px)"
srcset="images/largeme.jpg">
<source media="(min-width: 465px)"
srcset="images/medme.jpg">
<!-- <img src="images/smallme.jpg"alt="hero profile">-->
</picture>
commenting out the img fallback tag and it doesn't show anything.
I'm running Chrome 52 which should support picture element. But it seems to be acting as if it doesn't support it or something. What am I doing wrong here?
The img element inside the picture element isn't optional. The picture wrapper and its source elements are there to change the img, not replace it.
It should work in chrome, maybe you need the viewport meta-tag to trigger the different sources? <meta name="viewport" content="width=device-width, initial-scale=1"> Here is a simple picture-tag example which works in chrome. Compare it with your site to find out what is different.
It sounds silly, but have you tried reverting the order? For some reason doing this made it work for me.
So, instead of:
<picture>
<source media="(min-width: 1000px)"
srcset="images/largeme.jpg">
<source media="(min-width: 465px)"
srcset="images/medme.jpg">
<img src="images/smallme.jpg"alt="hero profile">
</picture>
try this:
<picture>
<source media="(min-width: 465px)"
srcset="images/medme.jpg">
<source media="(min-width: 1000px)"
srcset="images/largeme.jpg">
<img src="images/smallme.jpg"alt="hero profile">
</picture>
You must set a max-width for the lower width image, otherwise it is the only one always served (you can see it in devtools network tab if you try).
Like this
<picture>
<source media="(min-width: 1000px)"
srcset="images/largeme.jpg">
<source media="(max-width: 999px)"
srcset="images/medme.jpg">
<img src="images/smallme.jpg"alt="hero profile">
</picture>
According to this source the <source> media attribute is not being supported at all...
According to caniuse, support is conditional on enabling experimental Web Platform features in chrome://flags

Picture element not choosing file it should

I have a simple picture element that should be display one of two pictures depending on the browser window size:
<picture>
<source src="images/still_life-650_medium_2x.jpg" media="max-width:899px" type="image/jpeg">
<source src="images/still_life-1600_large_2x.jpg" media="min-width:900px" type="image/jpeg">
<img src="images/still_life-1600_large_2x.jpg" alt="Old calculator and some fruit">
</picture>
However when I test it with the browser sized below 899px, no matter how small I resize it in fact, it always loads the "images/still_life-1600_large_2x.jpg" file (Using Chrome devtools to determine what file it is loading as the image looks the same).
Is there something wrong with the above code?
Deryck answered it in his comment.
<picture>
<source srcset="images/still_life-650_medium_2x.jpg" media="(max-width:899px)" type="image/jpeg">
<source srcset="images/still_life-1600_large_2x.jpg" media="(min-width:900px)" type="image/jpeg">
<img src="images/still_life-1600_large_2x.jpg" alt="Old calculator and some fruit">
</picture>