html icon indicating copy to clipboard operation
html copied to clipboard

Make <img> src and srcset attributes optional if the source set can be generated from previous sibling <source> elements

Open johannesodland opened this issue 6 months ago • 6 comments
trafficstars

What is the issue with the HTML Standard?

In https://github.com/whatwg/html/issues/9181 the src attribute was made optional if the srcset attribute is present.

At least one of the src and srcset attributes must be present.

However, it is possible to provide the source set through previous sibling <source> elements. When it is, it is not clear why either src or srcset must be provided on the <img> element.

Omitting src and srcset works fine in practice when the source set is provided through <source> elements, except for the complete getter steps returning early.

Could we update the complete getter steps and make both src and srcset optional in these cases?

johannesodland avatar May 15 '25 19:05 johannesodland

That would also require a parent picture element presumably. Given the number of years picture has been supported that kind of relaxation of the rules is probably reasonable.

cc @zcorpan @sideshowbarker

annevk avatar May 16 '25 07:05 annevk

The img element is like the "last" source element. Why should srcset be optional? Should it be optional on source as well? What's the use case?

zcorpan avatar May 19 '25 14:05 zcorpan

The img element is like the "last" source element. Why should srcset be optional? Should it be optional on source as well? What's the use case?

The use case is to make it easier for authors to write (and read) code that generates compliant <picture> elements with multiple sources. I don't see any reason to make srcset optional on <source>.

Given a list of source sets provided from a CMS. It is simpler to output a <source> element for each source set when you don't have to special case and add one of them to the <img> element.

function renderPicture(sources) {
  return `<picture>
  ${sources.map(s => `<source srcset="${s.srcset}" media="${s.media}" type="${s.type}" />`)}
  <img alt="Description of image" loading=lazy sizes=auto />
</picture>`
}

Given two image Ids, one for dark and one for light mode, outputting generated <source> elements are simpler if you don't have to special case one of the generated urls:

function renderPicture(lightId, darkId) {
  return `<picture>
  ${types.map(type => `<source srcset="https://example.com/image/${darkId}/${type}" media="(prefers-color-scheme: dark)" type="${type}" />`)}
  ${types.map(type => `<source srcset="https://example.com/image/${lightId}/${type}" type="${type}" />`)}
  <img alt="Description of image" loading=lazy sizes=auto />
</picture>`
}

I'd rather flip the question. Why should srcset or src be mandatory on an <img> element when they are provided by <source> elements? The src attribute is optional in similar situations on the <video> and <audio> elements.

Right now it seems like it adds to the burden of authors, while not serving any obvious purpose?

johannesodland avatar May 20 '25 15:05 johannesodland

Thanks, that seems reasonable.

The original motivation to require src was to act as fallback for UAs that don't support srcset or picture. Now we have made the call that it's no longer needed, srcset on img is supported across browsers and search engines.

picture is supported across browsers, too, but I don't know the situation with search engines. We can file bugs though. cc @foolip

https://www.12gobiking.nl/winkel has

<picture>
    <source type="image/webp" preload-image="" srcset="https://www.12gobiking.nl/media/fit?url=https%3A%2F%2Fwww.12gobiking.nl%2Fmedia%2Fcms%2F2024%2Fwinkel%2F12GO_PANDEN.jpg&amp;width=1200&amp;height=1000&amp;quality=80&amp;type=webp" media="(min-width: 768px)">
    <source type="image/jpeg" preload-image="" srcset="https://www.12gobiking.nl/media/fit?url=https%3A%2F%2Fwww.12gobiking.nl%2Fmedia%2Fcms%2F2024%2Fwinkel%2F12GO_PANDEN.jpg&amp;width=1200&amp;height=1000&amp;quality=80&amp;type=jpeg" media="(min-width: 768px)">
    <source type="image/webp" preload-image="" srcset="https://www.12gobiking.nl/media/fit?url=https%3A%2F%2Fwww.12gobiking.nl%2Fmedia%2Fcms%2F2024%2Fwinkel%2F12GO_PANDEN.jpg&amp;width=1000&amp;height=1000&amp;quality=80&amp;type=webp" media="(max-width: 767px)">
    <source type="image/jpeg" preload-image="" srcset="https://www.12gobiking.nl/media/fit?url=https%3A%2F%2Fwww.12gobiking.nl%2Fmedia%2Fcms%2F2024%2Fwinkel%2F12GO_PANDEN.jpg&amp;width=1000&amp;height=1000&amp;quality=80&amp;type=jpeg" media="(max-width: 767px)">
    <img alt="Fietsenwinkel 12GO Biking" loading="eager" class="" width="1667" height="389" style="aspect-ratio: 1667 / 389">
  </picture>

I don't see this image in Google image search nor Bing image search.

See httparchive query results.

zcorpan avatar May 21 '25 09:05 zcorpan

The issue I filed for https://github.com/whatwg/html/issues/9181 was resolved and I can file another issue given a clear description.

Is the suspicion that <picture> is entirely unsupported by Google image search, or just that a src or srcset on <img> is required for it to be recognized?

foolip avatar May 28 '25 12:05 foolip

My suspicion is that it's entirely unsupported, but src or srcset being required would be equally problematic.

zcorpan avatar May 28 '25 19:05 zcorpan