Search code examples
htmlcssimagebrowsersrcset

Correct use of sensitive retinal images with "srcset"


I could not get the correct information or There is quite a lot of dirty information on this subject. It took me a while to understand the relationship between srcset and sizes and I was able to learn by trial and error.

  • According to the assumptions, if we use this technology, the browser always prefers the image it will use.
  • <picture> allows us to choose which image we want to use as well as responsive.

If there is anything wrong with what I have understood so far, please correct it. Because we haven't started "Retina" yet.

Let's continue with "srcset"

<img srcset="./1000x1000.jpg 1000w, ./800x800.jpg 800w" sizes="(max-width:800px) 100vw, 800px" />

If we interpret the above scenario,

  • Set the image to full size until the width is 800px.
  • Force the image to stay at 800px when the width exceeds 800px.
  • While all this is happening, choose the most suitable image from the "srcset" we have defined.

If I am lacking information up to this point, please correct it.

What about the retina?

In the scenario above, the browser preferred the most suitable image. But is it sensitive to "Retina" displays?

Ok now a new example,

<img srcset="./1000x1000.jpg 1000w, ./500x500.jpg 500w" sizes="(max-width:500px) 100vw, 500px" />

In the example above, we have defined two images that are 1000 and that is exactly 500px wide.

If we interpret the above scenario,

  • Set the image to full size until the width is 500px.
  • Force the image to stay at 500px when the width exceeds 500px.
  • While all this is happening, choose the most suitable image from the "srcset" we have defined.
  • Q: In a situation where it should prefer 500px, is it capable of automatically choosing "1000px" which is the "retina" equivalent of this?
  • Q: Or do we need to define it as "./1000x1000.jpg 500w 2x" via "srcset"?
  • Q: One last question, "750x750.jpg 500w 1.5x", why isn't anyone using this command? As far as I know, Android devices have a ratio of "1.5:1". But I see it is set to only "2x" in each example/guide.

Solution

  • Your assumptions look mostly correct to me (not sure about the lack of materials).

    Although few points worth mentioning:

    • It's not valid to use multiple size descriptors together ./1000x1000.jpg 1000w 2x. When running through an HTML validator you'd get:

      Error: Bad value ./1000x1000.jpg 1000w 2x for attribute srcset on element img: Expected single descriptor but found extraneous descriptor 2x at …0.jpg 1000w 2x .

    • It's not valid to use pixel density (1x, 2x, 3x) together with the sizes attribute. So it's either same image in different resolutions or widths+sizes:

        <img srcset="./500x500.jpg, ./1000x1000.jpg 2x" src="./500x500.jpg" />
        <img srcset="./500x500.jpg 500w, ./1000x1000.jpg 1000w" sizes="(max-width:500px) 100vw, 500px" />
      

      When running a mix of these through HTML validator you'd get:

      Error: Bad value ./500x500.jpg 1x, ./1000x1000.jpg 2x for attribute srcset on element img: Expected width descriptor but found 1x at …500x500.jpg 1x,. (When the sizes attribute is present, all image candidate strings must specify a width.)

    • Always add the src attribute to an image as well. Older browsers which do not support srcset will resort to using src. HTML validator will also give an error about this. By the spec the img element has two required attributes, rest are optional:

        src: The source location (URL) of the image file. 
        alt: The alternate text.
      

    Regarding your questions,

    Q: In a situation where it should prefer 500px, is it capable of automatically choosing "1000px" which is the "retina" equivalent of this?

    Yes. In your example it would automatically use 1000px image on @2x displays.

    Q: Or do we need to define it as "./1000x1000.jpg 500w 2x" via "srcset"?

    That's not valid HTML.

    Q: One last question, "750x750.jpg 500w 1.5x", why isn't anyone using this command? As far as I know, Android devices have a ratio of "1.5:1". But I see it is set to only "2x" in each example/guide.

    Using both descriptors is not valid as described before. Using 1.5x as one of the possible image densities is valid. An example of 1.5x is even listed in this MDN Web Docs article


    You could also experiment yourself by looking at the Network tab in developer tools, or use JS document.querySelector('img').currentSrc to check which images were actually requested. Additionally the MDN article provided above seems useful and run some of your examples through an HTML Validator.