Working on a portfolio for a photographer / videographer and trying to find a good balance between fast load and good image quality on mobile devices.
So far, I'm keen to bet on the picture element to load multiple versions of the images based on device max width like so:
<picture>
<source media="(max-width: 360px)"
srcset="picture_small.jpg">
<source media="(max-width: 640px)"
srcset="picture_medium.jpg">
<source media="(max-width: 1366px)"
srcset="picture_large.jpg">
<img src="picture_original.jpg" width="6000" height="4000"
alt="Really usefull description for each image">
</picture>
My concern is that the "alt" attribute will be ignored all together by user agents for the first 3 versions of the picture and hope of search engines to use it is also a long shot.
The <picture> element is a container only. The <img> element is the main part describing its contents. <source> only describes different sources. So the alt remains the same for all of them.
You cannot have a picture element without an img element. alt is a requirement in <img> and is part of its specification in the standard.
Related
I know the solution is <picture>
but which format is standard?
1.
<picture>
<source type="image/webp" srcset="pic.webp">
<img src="pic.jpg" alt="test">
</picture>
2.
<picture>
<source type="image/webp" srcset="pic.webp">
<img src="pic.jpg" alt="test" type="image/jpeg">
</picture>
3.
<picture>
<source type="image/webp" srcset="pic.webp">
<source type="image/jpeg" srcset="pic.jpg">
<img src="pic.jpg" alt="test">
</picture>
Number 1 would be the standard way of doing it.
When using the <picture> element the browser looks through each <source> element – starting from the top – to find an image that best fits the the current scenario. In your case it would only be if it supports the format in the type attribute. But it could also look for things like media queries in the media attribute or the pixel density of the user's screen if you add 2x or 3x versions in the srcset list.
As stated on MDN, if the browser can't find a fitting match in the <source>s, it defaults to the <img> tag:
The <img> element serves two purposes:
It describes the size and other attributes of the image and its
presentation. It provides a fallback in case none of the offered
<source> elements are able to provide a usable image.
So the JPEG in your example doesn't need to have a <source> as well, because it will be chosen if none of the <source>s are used.
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>
I have the following code, which I am using for image-gallery, but am not able to make it work:
<picture>
<source srcset="/web/gallery/17/1567772625.webp" type="image/webp">
<source srcset="/web/gallery/17/1567772625.jpg" type="image/jpg">
<source srcset="/web/gallery/17/1567772625-thumb.webp" type="image/webp">
<source srcset="/web/gallery/17/1567772625-thumb.jpg" type="image/jpg">
<a class="mg-image-wrap" data-title="Snaps From The Resort" href="/web/gallery/17/1567772625.jpg">
<img alt="Snaps From The Resort" class="mg-image" data-position="0" src="/web/gallery/17/1567772625-thumb.jpg" />
</a>
</picture>
However, if I change the code to the following:
<picture>
<source srcset="/web/gallery/17/1567772625-thumb.webp" type="image/webp">
<source srcset="/web/gallery/17/1567772625-thumb.jpg" type="image/jpg">
<img src="/web/gallery/17/1567772625-thumb.jpg" />
</picture>
I have two questions:
How I can make the the first block download webp, where supported, particularly thumbnail image is downloaded as jpg?
How to prevent href image not to download till user click on href link?
Picture element
Well, first of all, only <source> and <img> elements are allowed INSIDE a <picture>. That means if want it to link somewhere you should wrap the picture in the anchor tag or use a javascript click handler on the picture.
<a href="#">
<picture>...</picture>
</a>
Using Webp
You should treat the <picture> as a single element with multiple properties just like any other image. This means thumbnails and gallery images are separate and use JS to interact/change the "visible" image.
Basically, the browser grabs the first image that matches its abilities. (that's why the img tag is last)
You CAN specify different sized images inside a picture element by using media-queries BUT those are designed to load different images based on layout size NOT for different interactions/use cases.
Example:
<picture>
<source srcset="imageOne.jpg" type="image/jpg" media="(min-width: 1400px)">
<source srcset="mediumImg.jpg" type="image/jpg" media="(min-width: 800px)">
<source srcset="smallImg.jpg" type="image/jpg" media="(min-width: 400px)">
<img src="fallback.jpg" />
</picture>
This will cause the device to load different images based on device width...
You can also add any additional attributes directly on the picture tag like you would any other image.
<picture class="mg-image" data-position="0" >
...
</picture>
I am using <picture> tags. My target group uses modern browsers, so as soon as Firefox supports WebP there is no need to use the <img> tag.
Now:
<picture>
<source srcset="image-200px.webp 1x, image-400px.webp 2x" type="image/webp">
<img src="image-200px.jpg" alt="Description">
</picture>
Soon:
<picture>
<source srcset="image-200px.webp 1x, image-400px.webp 2x">
</picture>
Is there a way to implement an alt attribute for <picture> when not using the <img> tag?
My target group uses modern browsers so. As soon as Firefox support WebP there is no need to use the <img> tag
While you might not care about supporting browsers which do not support the <picture> element, the HTML specification says:
Content model:
Zero or more source elements, followed by one img element, optionally intermixed with script-supporting elements.
The img element is mandatory, so the alternative text is still provided by the alt attribute on the img element.
The <picture> tag will fall back to the string written inside the tags, so if you write
<picture>
<source srcset="image-200px.webp 1x, image-400px.webp 2x">
Some description
</picture>
You will see the description if the browser doesn't support the tag or image is unavailable.
I am trying to use picture Tag in react app (jsx file) but it doesn't seems to work.
Here is my code
<picture>
<source media="(min-width: 1024px)" src="image_Desktop.png"/>
<source media="(max-width: 768px)" src="image_Mobile.png"/>
<source media="(min-width: 768px) and (max-width: 1024px)" src="image_Tab.png"/>
<img src="image.png" alt="" styleName='brain-image'/>
</picture>
I tried giving attribute as srcset/src both in source tag but still not working.Any solution for the above problem?
If you are using srcset instead of using srcSet (with capital), this could be your problem.
Here is the another problem caused by usage of srcset:
Why is React.js removing the srcset tag on <img />?
As per the Official Doc :
The HTML <picture> element is a container used to specify multiple
elements for a specific contained in it. The browser
will choose the most suitable source according to the current layout
of the page (the constraints of the box the image will appear in) and
the device it will be displayed on (e.g. a normal or hiDPI device.
And img is a DOM element but a javascript expression.
Possibly duplicate of this React img tag issue with url and class
If this doesnt help you , please share the inspected HTML for this Component