When loading an image, historically I loaded the largest size of the image that would be used.
example.jpg is an 1170px wide image for large screens. On small screens this big image is loaded but scaled down to display properly.
The important thing to note here is even if the image is only displaying at 400px wide, the load time and bandwidth used are based on the size of the full 1170px wide image.
This can be improved with the
srcset attribute (pronounced “source set”).
If an attribute, like
srcset, is not recognized by a browser it is ignored. This fact allows us to use
srcset freely since older browsers will ignore
srcset and use
src instead. For this reason, we include the
src attribute pointing to the large image just as we have in the past.
srcset on Modern Browsers
If a browser does support
srcset, the browser will intelligently load one of the images listed.
Note I use lots of whitespace to make the markup easier to read.
<img srcset=" images/example-300x300.jpg 300w, images/example-768x768.jpg 768w, images/example-1024x1024.jpg 1024w, images/example.jpg 1170w" src="images/example.jpg" alt="Example">
There are multiple image definitions in srcset and they are separated by commas (
,). Each image definition is made up of two parts and separated by one or more spaces:
- the URL for the image
- the width of the image in px (e.g.
When loading, the browser uses the width of its own window as a guide to choosing the smallest version of the image that is at least as wide as the browser window.
For example, if our browser window is 700px wide, the
768w image will load (
images/example-768x768.jpg) because it is the smallest width that is equal to or bigger than the browser window (700px).
|Browser Window Width||likely image size loaded†|
|300 with 2x pixel density*||
* High Pixel Density Screens Impact our Calculations
† See “Why Likely Image Size Loaded?” below
High Pixel Density Screen
Some devices have High Pixel Density Screens, e.g. the Mac Retina series. For these high pixel density screens, it is common to have double the number of vertical and horizontal pixels (a
2x display). A
2x display means a
320x568 screen can display
640x1136 pixels. Some higher pixel density devices display
3x or even
4x resolution but for simplicity we’ll focus on
2x density allows the browser to replace a
300x300 image with a
600x600 image on a webpage and it will still appear the same size as the
300x300 but will display the image with a higher resolution.
In the example chart above, a browser width of 300px on a
2x screen can accommodate a 600px wide image so the
768w would be the size most likely chosen by the browser.
While this can get confusing, don’t get hung up on it. The browser does all the hard work of choosing which size to display. You list the different image URLs and their widths in the
srcset attribute and the browser determines the best image size and loads it.
Why Likely Image Size Loaded?
I say “likely image size loaded” because choosing the most appropriate image to load is a decision left up to the browser. As of this writing, browsers determine the smallest image that properly fits in the area but it is likely we’ll see more advanced behavior from browsers in the future. For example, I can imagine in the future a browser on a mobile device with a slow connection may choose smaller image sizes to save bandwidth and speedup loading.
Sizes Attribute (Not all Images are the Full Screen Width)
You may have noticed, we refer to the browser window width when determining what size image to load. Wouldn’t it make more sense to load an image based on how big it is displayed on the page. For example, if an image takes up only half the width of the page shouldn’t we use that size when deciding which image to load.
The problem here is we want to start loading the image right away (i.e. we don’t want to wait for the CSS to load and be applied first). In many cases the CSS being applied to the page affects the size an image is ultimately displayed.
In other words we need more information when choosing our image and this information comes in the form of the
For example if we assume our
example.jpg will be displayed in half the width of the page we can use
sizes="50vw" (which indicates 50% of the viewport width).
Now our code looks like this
<img srcset=" images/example-300x300.jpg 300w, images/example-768x768.jpg 768w, images/example-1024x1024.jpg 1024w, images/example.jpg 1170w" sizes="50vw" src="images/example.jpg" alt="Example">
Media Queries and the Sizes Attribute
If you’re a big fan of Bootstrap like me, you may have the problem where your image takes up half the width of the page (6 of the 12 grid columns) but on narrow screens the grid collapses and the images become full width. For me this collapse occurs below
768px. We can modify our
sizes attribute to accommodate for this with:
sizes="(min-width: 768px) 50vw, 100vw"
This says for any screen widths
768px or greater our image will take up 50% of the horizontal view port. Otherwise our image will take up 100% of the horizontal view port.
sizes attribute allows you to refine how sizes are chosen.
Our final code looks like
<img srcset=" images/example-300x300.jpg 300w, images/example-768x768.jpg 768w, images/example-1024x1024.jpg 1024w, images/example.jpg 1170w" sizes="(min-width: 768px) 50vw, 100vw" src="images/example.jpg" alt="Example">