Skip to content

Instantly share code, notes, and snippets.

@cathyxz
Created April 29, 2019 20:52
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cathyxz/f17d12c07d60bcef52591e64e5e684fb to your computer and use it in GitHub Desktop.
Save cathyxz/f17d12c07d60bcef52591e64e5e684fb to your computer and use it in GitHub Desktop.
Srcset and Sizes

Srcset and Sizes

Did some experimentation to figure out how different browsers behave with regards to the srcset and sizes attribute in various browsers. Documented below.

srcset + sizes behavior

Vanilla No AMP No CSS Example: https://codepen.io/cathyxz/pen/vbLrrE

<img srcset="https://placekitten.com/200/200 200w,
             https://placekitten.com/300/300 300w,
             https://placekitten.com/400/400 400w,
             https://placekitten.com/600/600 600w
             https://placekitten.com/800/800 800w"
     sizes="(max-width: 320px) 200px,
            (max-width: 480px) 300px,
            (max-width: 640px) 400px,
            (max-width: 800px) 600px,
            100vw">
</img>

Chrome

Fetches a new image on viewport increase. Does not re-fetch anything on viewport size decrease.

Screen width (breakpoint) Image natural width Image actual width Media query matched
< 320 px 400px 200px Max-width: 320px
< 480 px 600px 300px Max-width: 480px
< 640 px 800px 400px Max-width: 480px
>= 640 px 800px 600px

Safari

Doesn’t refetch on viewport change at all. Fetches as follows on refresh only.

Screen width (breakpoint) Image natural width Image actual width Media query matched
< 321 px 400px 200px Max-width: 320px
< 482 px (+/-1) 600px 300px Max-width: 480px
< 641 px 800px 400px Max-width: 480px
>= 641 px 800px 600px

Firefox

Refetches on viewport change at every breakpoint, regardless of increase or decrease.

Screen width (breakpoint) Image natural width Image actual width Media query matched
< 321 px 400px 200px Max-width: 320px
< 481 px 600px 300px Max-width: 480px
< 641 px 800px 400px Max-width: 480px
>= 641 px 800px 600px

srcset without sizes behavior

Sample code here: https://codepen.io/cathyxz/full/KEVPKG

<img srcset="https://placekitten.com/200/200 200w,
             https://placekitten.com/300/300 300w,
             https://placekitten.com/400/400 400w,
             https://placekitten.com/600/600 600w
             https://placekitten.com/800/800 800w">
</img>

Chrome

Fetches a new image on viewport increase. Does not re-fetch anything on viewport size decrease. Basically assumes image is 100vw and fetches image accordingly.

Screen width (breakpoint) Image natural width Image actual width
< 125 px 200px 100vw
< 175 px 300px 100vw
< 250 px 400px 100vw
< 350 px 600px 100vw
>= 350px 800px 100vw

Firefox

Regardless of screen size, always picks the largest src in the srcset. Does not update on viewport change. Does not update on refresh.

Safari

Regardless of screen size, always picks the largest src in the srcset. Does not update on viewport change. Does not update on refresh.

Browser Specifications

Note that the relevant browser spec for this is: https://html.spec.whatwg.org/multipage/images.html#reacting-to-environment-changes

The user agent may at any time run the following algorithm to update an img element's image in order to react to changes in the environment. (User agents are not required to ever run this algorithm; for example, if the user is not looking at the page anymore, the user agent might want to wait until the user has returned to the page before determining which image to use, in case the environment changes again in the meantime.)

@ciriousjoker
Copy link

Chrome seems to fetch bigger images, not "on viewport increase".

Example:

  • image with regular size is for mobile, thumbnail at trash quality for desktop
  • making the viewport smaller will load the good resolution image, but making it bigger wont fall back to the trash quality

@cathyxz
Copy link
Author

cathyxz commented Mar 18, 2023

Ah, this is very old research (4 years old) at this point. I think this behavior was tested at the time it was written, but I would not be surprised if browser updates have since made this extremely obsolete indeed I am surprised that it is still read. Thank you for the updated notes on this behavior. =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment