High resolution images are something we all want. Whether it’s on a mobile phone, a desktop or a laptop - no one wants to look at a blurry image. There are multiple ways to achieve this, but today we’re going to look at a solution simple to achieve with HTML. Let’s have a look at the srcset
attribute.
The srcset
attribute gives you the option to specify multiple images and let the browser decide what the best image is.
Table of contents
Let’s start with something simple:
<img src="/photo-small.jpg">
This is a normal image include which can be viewed on a normal laptop or for example a MacBook with a retina display. To get a high resolution version on a retina display we’d have to use media queries in CSS.
This would be your HTML:
<div class="low-res">
<img src="/photo-small.jpg">
</div>
<div class="high-res">
<img src="/photo-large.jpg">
</div>
As we mentioned, we’d need some CSS magic to let the browser know - hey, this is what I want to use when a user is visiting the website on a retina display.
.high-res {
display: none;
}
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.low-res {
display: none;
}
.high-res {
display: block;
}
}
Now this is all super fancy, but there’s a much simpler way of doing this. And we can do it with pure HTML!
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
The srcset attribute
This is where our new srcset
attribute comes in. We’re basically moving all our CSS rules over to just one simple line, which would look like this:
<img src="/photo.jpg" srcset="/[email protected] 2x">
Let’s start dissecting what I’ve just shown you to get a better understanding of what’s going on in our new srcset
attribute.
Conventions
As you can see I’ve used a rather weird name for photo.jpg
which I changed to [email protected]
. This is simply our original file, but exported twice the size. That’s why I have postfixed it with @2x
. We’ve used an example with just 1 specific image size in srcset
, but there could be 4 for example - which we will get on to later!
Here’s a quick example of how I would manage my files in srcset
and make sure they’re making sense for everyone else who’s also going to work with your images and HTML.
<img src="/photo.jpg" srcset="/[email protected] 2x, /[email protected] 1000w" />
Note: we’re using widths here because srcset only works based on width or pixel density (1x, 2x, etc). You can’t specify an image based on a certain height of the screen.
Browser calculations
Before we go into all the specifics about different ways to specify your image widths. Let’s have a look at how your browser actually picks the image.
Your browser attempts to calculate the best fit image based on the device width. For regular devices the ratio it is looking for is 1. If the device is considered “retina” then the browser will multiply the result by 2 to find the best image size.
Multiply what you might ask? We’ve got a set of images of 500px, 1250px and 2500px.
The device we’re using has a width of 1000px, now let’s look at the calculations the browser makes:
500 / 1000 = 0.5
1250 / 1000 = 1.25
2500 / 1000 = 2.5
As we mentioned earlier, on non-retina devices the browser will try and match a ratio of 1. This means for this device it will pick the image of 1250px as it’s the closest to 1.
A retina display has a ratio of 2. This is where our multiply comes in. The browser will look at 1.25 and go, this image will be too small and will lose quality. It will then multiply 1.25 by 2 and see if there’s anything available.
There’s a 2500px image with a ratio of 2.5 which matches what the browser is looking for so it will automatically load in that image for optimum result.
The srcset attribute
Now we’ve talked about conventions and how the browser picks the image, let’s have a look at how the srcset
attribute is made up and how we can declare the images.
Note: source set takes 2 values and is separated by a comma after each declaration.
Let’s have a look:
<img src="/photo.jpg" srcset="/[email protected] 1000w, /[email protected] 2x, /[email protected] 3x" alt="" />
You can see that every line is made up out of a file you wish to load in and after that a space with the width of the image’ real size. In this case, we’ve got an image with a width of 1000px. So we say when the width (w) of the screen is 1000px, load in that image.
Now there’s another attribute which I’ve not discussed out there that works together with our sourceset. This is the sizes
attribute. Now when sizes has not been specified, it’s default value is always 100vw
(100% of your device viewport).
Next one in line is 2x
. We’ve discussed this a bit already but it’s the device-pixel ratio we’re specifying here. When the device has 2x the amount of pixels than a regular 1x device, it will automatically grab the image specified and load it in.
You all can guess what 3x
is going to do! As you can see srcset
is quite a powerful tool to make your images responsive and you didn’t need a single line of CSS for it.
Conclusion
If you’re a developer who’s looking for an easy way to specify your responsive images, source set is the way to go! There are loads of frameworks out there who would make the use of source sets an even bigger asset. Think about how dynamic it could be.
CSS limits us as we can’t target something in a CSS file. The media queries we write will and remain the same. Our HTML can be be changed and manipulated, which opens a lot of doors when it comes to the srcset
attribute!