Using the code below, I am trying to achieve this:
<source>
and JPEG in<img>
(as fallback)src
attribute of <img>
in place, which points to a low-res lazyload versionspecify width
and height
of image in HTML specified for SEO/UX reasons (more below).
<div>
<picture>
<source type="image/webp"
data-srcset="
image_100.webp 100w,
image_200.webp 200w,
image_400.webp 400w,
image_600.webp 600w,
image_754.webp 754w"
data-sizes="(min-width: 1058px) 1000px, 100%" />
<img data-srcset="
image_100.png 100w,
image_200.png 200w,
image_400.png 400w,
image_600.png 600w,
image_754.png 754w"
data-sizes="(min-width: 1058px) 1000px, 100%"
src="image_min.png" width="1000" height="300" alt="image_alt" />
</picture>
</div>
Why are there a data-
prefixes, you ask? I want to use a lazyloading script, which will remove them, at the right time, when the image should be displayed.
Before the lazyloading script kicks in, the browser will ignore the <source>
element, because proper srcset
and sizes
will be absent at that point. The browser will also ignore data-srcset
and data-sizes
of <img>
, and will, therefore, display a low-res/placeholder image as defined in src
.
Knowing the image dimensions and thus w/h ratio, I also want to supply these, in HTML, so that the browser knows what space to reserve for the image during loading time, before the images are loaded, to prevent re-rendering.
Simply setting absolute values of the image into style
or into width
and height
attributes of the <img>
, are only valid for viewport width >1058px. Otherwise, the dimensions are relative to viewport size. So, I want to tell the browser, that the image will have a width 100% and height 30% of width of parent <div>
, which si valid in all cases.
I know that there is a css padding-top
trick, to keep aspect ratio of a div, but I'm not sure I can use it in theis scenario, since it actually creates a padding above the image.
Any other ideas on setting the fallback image dimension?
Ok, so a plausible answer is, after all, wrapping the <picture>
in a <div>
container and applying CSS, including the padding-top
hack, to maintain its' aspect ratio:
<div style="position:relative;"width:100%;padding-top:33%>
<picture>
<source type="image/webp"
srcset="
image_100.webp 100w,
image_200.webp 200w,
image_400.webp 400w,
image_600.webp 600w,
image_754.webp 754w"
sizes="(min-width: 1058px) 1000px, 100%" />
<img srcset="
image_100.png 100w,
image_200.png 200w,
image_400.png 400w,
image_600.png 600w,
image_754.png 754w"
sizes="(min-width: 1058px) 1000px, 100%"
src="image_min.png" style="width:100%;height:100%;position:absolute" alt="image_alt" />
</picture>
</div>
<img>
: width
and height
set to 100%, and position:absolute
<div>
wrapper must be CSS position:relative
, for the image to be positioned inside it "absolutely".<div>
must have width
and padding-top
set to reflect the dimensions/aspect ratio of the image. It works as follows:
The <img>
element fills up the <div>
wrapper completely. Thanks to position:absolute
, the padding-top
of the <div>
wrapper has no effect on position of the image. The percentage value of padding-top
makes it relative to the element width, so aspect ratio remains constant (e.g. padding-top
set to 100% would make the wrapper always square).
The main benefit for SEO/UX:
No matter what the sizes
and the srcset
values are, if the dimensions (thus aspect ratio) are known, we can create a placeholder using CSS of the fallback <img>
, and so reserving space for an image which has not yet been loaded, or even chosen by the browser from the srcset
.
Ultimately this will prevent annoying changes in page layout, caused by images being painted on a page which has alreadey been rendered.