You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the output of the ?picture directive does not export a height and prevents the use of the ?meta directive to retrieve it. This makes it difficult to have a set height on the <img>.
Both width and height are required for the browser to automatically calculate the aspect-ratio of the <img> before the image file is loaded. As a result, the browser can reserve the necessary space and prevent Cumulative Layout Shift (CLS).
Before the ?picture directive was available, the ?meta directive was used to manipulate the strings generated for a <picture> element.
For example, this is an <Image> component in Svelte using the ?meta directive (adapted from this code).
<scriptlang="ts">import{onMount}from'svelte';exportletalt: string;exportletplaceholder='';exportletdominantColor='#F8F8F8';exportletloading: 'eager'|'lazy'='lazy';exportletdecoding: 'async'|'sync'|'auto'='async';exportletstyle='';letclassName='';export{classNameasclass};interfaceImageMeta{
src: string;
width: number;
height: number;
format: string;}// expects the output from the directives:// ?w=1920;1366;780;414&format=avif;webp;jpg&meta=width;height;src;format
export letmeta: ImageMeta[];// if there is only one, vite-imagetools won't wrap the object in an arrayif(!(metainstanceofArray))meta=[meta];// all images by formatletsources=newMap<string,typeofmeta>();meta.map((m)=>sources.set(m.format,[]));meta.map((m)=>sources.get(m.format)?.push(m));// fallback image: first resolution of last formatletfallback=sources.get([...sources.keys()].slice(-1)[0])?.[0];exportletsizes=`${fallback?.width}px`;// fade-in the image after it has loadedletimage: HTMLImageElement;lethidden=false;onMount(()=>{if(image.complete)return;hidden=true;image.onload=()=>(hidden=false);});</script><div{style}style:background-image={placeholder?`url(${placeholder})`: ''}
style:background-color={dominantColor}class="img__placeholder {className}"
><picture>
{#each [...sources.entries()] as [format, meta]}
<source{sizes}type="image/{format}"
srcset={meta.map((m) => `${m.src} ${m.width}w`).join(', ')}
/>
{/each}
<imgbind:this={image}{style}class={className}class:hiddensrc={fallback?.src}width={fallback?.width}height={fallback?.height}{alt}{loading}{decoding}
/>
</picture></div><style>
.img__placeholder,
img {
height: auto;
width: 100%;
}
.img__placeholder {
background-repeat: no-repeat;
background-size: cover;
overflow: hidden;
}
img {
display: block;
object-fit: cover;
transition: opacity 0.25s ease-out;
/* hide alt text while image is loading */
color: transparent;
}
.hidden {
opacity: 0;
}
</style>
Suggestion
Currently, the ?picture directive outputs something like this:
I also wonder if generating a low-quality placeholder base64 string could be included. sharp already has an option for generating base64 strings from images. I've been generating placeholders using the ?w=54&blur=2&jpg directive, but these don't get inlined as base64.
This is a suggestion that builds upon #369
Problem
Currently, the output of the
?picture
directive does not export aheight
and prevents the use of the?meta
directive to retrieve it. This makes it difficult to have a setheight
on the<img>
.Both
width
andheight
are required for the browser to automatically calculate theaspect-ratio
of the<img>
before the image file is loaded. As a result, the browser can reserve the necessary space and prevent Cumulative Layout Shift (CLS).Before the
?picture
directive was available, the?meta
directive was used to manipulate the strings generated for a<picture>
element.For example, this is an
<Image>
component in Svelte using the?meta
directive (adapted from this code).Suggestion
Currently, the
?picture
directive outputs something like this:Ideally, the fallback would include a
width
andheight
so theaspect-ratio
can be calculated.What are your thoughts @benmccann ?
Other thoughts
I also wonder if generating a low-quality placeholder base64 string could be included.
sharp
already has an option for generating base64 strings from images. I've been generating placeholders using the?w=54&blur=2&jpg
directive, but these don't get inlined as base64.EDIT: low quality placeholder issue already exists #86
The text was updated successfully, but these errors were encountered: