I'm scratching my head why Google Chrome loads JPG instead of Avif and WebP?
Here's my code:
<picture>
<source media="(max-width: 991px)" srcset="/assets/img/768w.avif" type="image/avif">
<source media="(max-width: 991px)" srcset="/assets/img/768w.webp" type="image/webp">
<source media="(max-width: 991px)" srcset="/assets/img/576w.avif" type="image/avif">
<source media="(max-width: 991px)" srcset="/assets/img/576w.webp" type="image/webp">
<img src="/assets/img/768w.jpg" alt="image" width="100%" height="auto" class="img-fluid" decoding="async" loading="lazy">
</picture>
First of all of your sources are specified for screens smaller than 991px – I guess you are loading page on larger device (or window width) so only default src fits the query.
The second mistake is expecting filename should be recognized as media query. I guess you are looking for something like this:
<source media="(max-width: 991px)" srcset="/assets/img/576w.avif 576w, /assets/img/768w.avif 768w" type="image/avif">
This means "while screen is smaller than 991px use avif. According to your screen pixel density and current width will be loaded one of two images".
Same for webp. You also need to specify sources for screens larger than 991px.
Take a look at this example
Related
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>
When I want to use webp images when the browser supports it and otherwise fallback to jpg I use like this:
<picture>
<source srcset="image.webp" type="image/webp" />
<img src="image.jpg" alt="Something">
</picture>
also to choose the suitable image size for the screen size:
<picture>
<source media="(max-width: 799px)" srcset="small.jpg">
<source media="(min-width: 800px)" srcset="big.jpg">
<img src="big.jpg" alt="something">
</picture>
As I have all images, with all sizes and both formats, I want to do both of the features above at the same time, so I have both webps of small and big sizes and both jpgs of big and small sizes. So If the browser supports webp, only use webp images of different sizes (based on screen size) and if not use jpg files of different sizes.
I wonder if this is possible.
I Tested it like this:
<picture>
<source media="(max-width: 799px)" srcset="small.webp">
<source media="(min-width: 800px)" srcset="big.webp">
<source media="(max-width: 799px)" srcset="small.jpg">
<source media="(min-width: 800px)" srcset="big.jpg">
<img src="big.jpg" alt="something">
</picture>
but it only chooses the first one matching the screen size
Of course it is possible. And it is pretty simple to be honest
<img src="images/keyboard.webp" onerror="this.src='images/keyboard.jpg';" alt="Image not found"/>
This code pretty much explains itself.
It loads webp image. onerror handles if image is not loaded. it sets src to jpg
You need to use the type attribute on each source, so the browser will be able to load the best frmat it understands, e.g.:
<picture>
<source media="(max-width: 799px)" srcset="small.webp" type="image/webp">
<source media="(min-width: 800px)" srcset="big.webp" type="image/webp">
<source media="(max-width: 799px)" srcset="small.jpg" type="image/jpeg">
<source media="(min-width: 800px)" srcset="big.jpg" type="image/jpeg">
<img src="big.jpg" alt="something">
</picture>
I'm concerned about <picture> and srcset on <source> behaviour. I want to load different pictures dependent on:
retina / non retina displays
screen resolution
webp format support
Code I've wrote (only for mobile):
<picture>
<source
media="(max-width: 767px)"
srcset="
https://i.ibb.co/W6v8K6J/mob-2x-webp.png 2x,
https://i.ibb.co/xzNtHnL/mob-webp.png 1x
"
type="image/webp"
/>
<source
media="(max-width: 767px)"
srcset="
https://i.ibb.co/DkyRD4z/mob-x2.png 2x,
https://i.ibb.co/qC1JqMR/mob.png 1x
"
type="image/png"
/>
<img src="" alt="Not mobile!" />
</picture>
It works, however it always loads retina image - also for non-retina displays. Does anyone know why? And how can I achieve all the points I've listed?
Link to sandbox: https://codesandbox.io/s/relaxed-cloud-txynh
Live preview: https://txynh.csb.app/
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
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>