sam
sam

Reputation: 10064

Serve an image at different size / resolution depending on device width and users bandwidth

Im building a website with a full screen background, the site is responsive and currently serves the same images to an iphone as it would do to a 27" monitor. Obviously the 27" monitor needs a higher res image, currently all devices / screen resolutions get the same images which are roughly 1900px wide, and weight around 300kb, these dont look as good as they could on an 27" screen, but i dont want to make them any bigger as there are 20 of them and a mobile user could take forever to load them.

Is there a way similar to media queries where i could serve an image based on the screen resolution and ideally bandwidth of the users device ?

Upvotes: 7

Views: 6928

Answers (2)

janfoeh
janfoeh

Reputation: 10328

Take a look at the <picture> element. It allows you to define several sources and select the correct one based on media queries:

<picture>
   <source media="(min-width: 480px)" srcset="tablet.png">
   <source media="(min-width: 1024px)" srcset="desktop.png">
   <img src="tablet.png" alt="A photo of London by night">
</picture>

While native support is as of yet limited, there is a polyfill available which extends compatibility. Older browsers simply ignore it and fall back to the included <img>.

For broadest support, you should combine it with the srcset attribute. See the picturefill documentation for examples.

Upvotes: 2

alexander farkas
alexander farkas

Reputation: 14134

For your use case, you can use srcset with the width descriptor and the sizes attribute.

The srcset attribute defines a list of image candidates and you describe the width of each image in pixel:

srcset="image-640.jpg 640w, image-980.jpg 980w, image-1240.jpg 1240w, image-1900.jpg 1900w, image-2400.jpg 2400w"

The sizes attribute describes how big you want to show this image. Here is an example:

sizes="(min-width: 2400px) 2400px, 100vw"

This mean, if the browser viewport is 2400 or larger you want to display it at 2400pixel otherwise you want to display it at full viewport width.

Together this looks something like this:

<img 
    srcset="image-640.jpg 640w, image-980.jpg 980w, image-1240.jpg 1240w, image-1900.jpg 1900w, image-2400.jpg 2400w" 
    sizes="(min-width: 2400px) 2400px, 100vw />

The picture element, which was described in the other answer, should be used, if you want to do so called art direction. Which means you want to use different images (in ratio, crop or something like this), in that case the order does matter. The browser takes the first source, which matches the media query.

<picture>
   <source media="(min-width: 1024px)" srcset="desktop.png">
   <source media="(min-width: 480px)" srcset="tablet.png">
   <source srcset="mobile.png">
   <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="A photo of London by night">
</picture>

srcset with sizes is supported in Chrome, Firefox and Safari 9 (not 8). To add support for Safari 8 and IE, you can use a polyfill (https://github.com/scottjehl/picturefill or https://github.com/aFarkas/respimage).

Upvotes: 8

Related Questions