Skip to content

Commit

Permalink
Use srcset and sizes on img element in picture
Browse files Browse the repository at this point in the history
Previously, in the case where the image has multiple formats and multiple sizes, elventy-img would generate output somewhat like

```
<picture>
<source type="image/webp" srcset="/img/KkPMmHd3hP-200.webp 200w, /img/KkPMmHd3hP-400.webp 400w" sizes="100vw">
<source type="image/jpeg" srcset="/img/KkPMmHd3hP-200.jpeg 200w, /img/KkPMmHd3hP-400.jpeg 400w" sizes="100vw">
<img alt="" src="/img/KkPMmHd3hP-200.jpeg" width="400" height="266">
</picture>
```

This change makes eleventy-img instead produce output like

```
<picture>
<source type="image/webp" srcset="/img/KkPMmHd3hP-200.webp 200w, /img/KkPMmHd3hP-400.webp 400w" sizes="100vw">
<img alt="" src="/img/KkPMmHd3hP-200.jpeg" srcset="/img/KkPMmHd3hP-200.jpeg 200w, /img/KkPMmHd3hP-400.jpeg 400w" sizes="100vw" width="400" height="266">
</picture>
```

This adds srcset and sizes to the img tag, and doesn't produce a source
tag for the same format provided by the img tag.

The initial motivation around this was to get RespImageLint to stop
complaining by adding srcset and sizes to the img tag. I'm not an HTML expert, and I'm not sure this change is strictly correct.
  • Loading branch information
adamwolf committed Nov 19, 2023
1 parent 46fe087 commit 5bdf390
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
27 changes: 25 additions & 2 deletions generate-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function generateObject(metadata, attributes = {}) {

let children = [];
values.filter(imageFormat => {
return imageFormat.length > 0 && (lowsrcFormat !== imageFormat[0].format || imageFormat.length !== 1);
return imageFormat.length > 0 && (lowsrcFormat !== imageFormat[0].format);
}).forEach(imageFormat => {
if(imageFormat.length > 1 && !attributes.sizes) {
// Per the HTML specification sizes is required srcset is using the `w` unit
Expand All @@ -118,8 +118,31 @@ function generateObject(metadata, attributes = {}) {
});
});

/*
Add lowsrc as an img, for browsers that don’t support picture or the formats provided in source
If we have more than one size, we can use srcset and sizes.
If the browser doesn't support those attributes, it should ignore them.
*/
let imgAttributes = Object.assign({}, attributesWithoutSizes);
if (Object.values(lowsrc).length > 1) {
if (!attributes.sizes) {
// Per the HTML specification sizes is required srcset is using the `w` unit
// https://html.spec.whatwg.org/dev/semantics.html#the-link-element:attr-link-imagesrcset-4
// Using the default "100vw" is okay
throw new Error(missingSizesErrorMessage);
}

let srcsetAttrValue = Object.values(lowsrc).map(entry => entry.srcset).join(", ");
if (srcsetAttrValue) {
imgAttributes.srcset = srcsetAttrValue;

imgAttributes.sizes = attributes.sizes;
}
}

children.push({
"img": attributesWithoutSizes
"img": imgAttributes
});

return {
Expand Down
3 changes: 1 addition & 2 deletions test/test-markup.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ test("Image markup (two widths)", async t => {
sizes: "100vw",
}), [`<picture>`,
`<source type="image/webp" srcset="/img/KkPMmHd3hP-200.webp 200w, /img/KkPMmHd3hP-400.webp 400w" sizes="100vw">`,
`<source type="image/jpeg" srcset="/img/KkPMmHd3hP-200.jpeg 200w, /img/KkPMmHd3hP-400.jpeg 400w" sizes="100vw">`,
`<img alt="" src="/img/KkPMmHd3hP-200.jpeg" width="400" height="266">`,
`<img alt="" src="/img/KkPMmHd3hP-200.jpeg" width="400" height="266" srcset="/img/KkPMmHd3hP-200.jpeg 200w, /img/KkPMmHd3hP-400.jpeg 400w" sizes="100vw">`,
`</picture>`].join(""));
});

Expand Down

0 comments on commit 5bdf390

Please sign in to comment.