html icon indicating copy to clipboard operation
html copied to clipboard

Controlling the appearance of images being loaded

Open Zirro opened this issue 6 years ago • 10 comments

The topic of how images can be presented while they are loading was recently brought up in an issue about loading images lazily. This seems like a discussion worth its own issue, since images can often be observed loading in the viewport even when they are not doing so lazily.

Here's a brief summary of the points made in that issue:

  • @domenic mentioned the possibility of bringing back the lowsrc attribute, which was previously used to display a smaller version of an image before the larger one in src had loaded.

  • Some comments discussed the use of CSS to display a placeholder. @othermaciej mentioned that a "CSS background-image with a data: URL seems like a pretty inelegant (and potentially inefficient) way to do it".

  • I added that some sites may be more inclined to use a solid colour - likely the dominant one from the loading image - rather than a smaller version of the image, and that CSS may not be the best way to supply either a placeholder image or colour given a strict CSP that forbids inline styles.

At the moment, some browsers display a blank box while others show the text of the alt attribute until an image has loaded. I believe it could be helpful to give developers a way to control the appearance of loading images that does not depend on either JS or CSS, making it possible for the browser to paint the placeholder at the earliest possible time and improve perceived loading speed.

Zirro avatar Apr 15 '18 20:04 Zirro

Additionally:

@smfr mentioned:

  • it needs to work with , srcset

@othermaciej mentioned:

We need to consider <picture> too, where different <source> images may need different placeholders, since they may not all have the same size.

@shallawa mentioned:

  • Since the placeholder can be an image itself, will a special load event fire when the placeholder image is loaded?
  • How can the user specify the transition from rendering the placeholder to rendering the actual image? Can something like this work?

img { placeholder-transition: opacity 1s linear; }

Malvoz avatar Apr 17 '18 16:04 Malvoz

This placeholder can also be relevant for <video> elements which often are used interchangeably as a replacement for GIFs. Considerations already made for the poster attribute (which isn't necessarily a small placeholder) would hopefully make this easier to implement.

Zirro avatar Apr 17 '18 17:04 Zirro

I strongly agree that, at minimum, giving a control over "just display the alt as inline text" vs "show a box with some placeholder" is important, and that it would be great to control the placeholder as well; tons of sites are doing this manually right now, so it's clearly an attractive cowpath for us to pave.

And yeah, whatever we end up doing, it needs to work on both img and source.

I would be remiss at this point if I didn't mention FLIF; if we just implemented that ("just"), there'd be no need for a low-src, you can just display whatever prefix of the file you've downloaded so far. (It even supports animation now! That's new and exciting!)

tabatkins avatar Apr 17 '18 21:04 tabatkins

Apparently there used to be a lowsrc attribute for <img>, but it’s listed as non-conforming with the following hint:

Use a progressive JPEG image (given in the src attribute), instead of using two separate images.

https://html.spec.whatwg.org/multipage/obsolete.html#attr-img-lowsrc

prlbr avatar Apr 21 '18 14:04 prlbr

I can imagine a few kinds of image placeholders that authors may want, for the case of lazy loading or slow loading:

  • A solid color
  • Another image, but one that is considerably smaller on the wire so it loads faster
  • A tiny (byte-wise) placeholder encoded as a data URL.
  • A tiny image passed through a blur filter like Medium does
  • A placeholder image made of inline SVG, possibly with filters, as in this technique (though note, inline SVG could also be represented as a data: URL)

For the case of an image failing to load or images being disabled, they may additionally want:

  • The alt text
  • A browser-provided "broken image" icon

I think we should keep these cases a bit separate. As far as I am aware, no popular website uses text as the placeholder for an image while loading is in progress.

FLIF is a neat way to address the slow-loading case, but it doesn't really work for the browser lazy loading case (in the rare case where the user's scrolling outpaces the browser's loading speed, particularly where the issue is latency rather than bandwidth) and it may not produce the desired aesthetic effect.

othermaciej avatar Feb 19 '19 20:02 othermaciej

Another placeholder technique:

  • A gradient.

I think a solid color and gradient are sufficiently handled using CSS, but other ideas could be explored. I suppose SVG could be used.

For the other cases, a new attribute like placeholder that takes a URL for an image. Potentially we could make URLs starting with # be able to point to an svg element, but that may be complicated to implement (?), and if we do this it would be inconsistent to not also support that elsewhere (like in <video poster>, <img src>, srcset...).

I think using lowsrc is not great because it is already exposed as an IDL attribute, which makes it harder to feature-detect.

zcorpan avatar Mar 06 '19 22:03 zcorpan

@zcorpan For my edification, how do you define a color or gradient placeholder for an image using CSS? Is there a CSS pseudo-class by this? If it's by setting an always-on background, that doesn't work for images with transparency.

I tend to agree that a new attribute is better than reusing lowsrc for the reason you gave.

othermaciej avatar Mar 06 '19 23:03 othermaciej

I was thinking of using 'background', but as you point out it would need to be turned off when the image is loaded. Also, it wouldn't work right if there's padding on the image.

Adding pseudo-classes for different states could help with styling, like https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading . That combined with 'background', or maybe 'content' if that should work for normal elements.

zcorpan avatar Mar 07 '19 08:03 zcorpan

Another placeholder technique that seems to be gaining traction is using a blurhash: https://github.com/woltapp/blurhash

We could add a single attribute to <img> e.g. <img blurhash="{hash}" src=...>, no need to rely on external resources, which is a quality what you want in a placeholder...

plinss avatar Oct 30 '20 04:10 plinss

The appearance of images with no src also needs to be controllable. Currently UAs draw an outline which is not overridable in CSS (https://bugs.webkit.org/show_bug.cgi?id=171326); ideally that rendering would be described in the UA stylesheet, allow authors to customize it.

So this proposal needs to cover both selector hooks allowing authors to style images in their various states, and the default UA style rules.

smfr avatar Jul 26 '22 17:07 smfr