EXPEDIA GROUP TECHNOLOGY — SOFTWARE
Images on the Web: Part 1 — Responsive Images
Avoiding the hazards of pixelation, slow loading, and poor cropping
The term responsive web has been with us since Ethan Marcotte, coined it when he published the article Responsive Web Design [1] in May 2010. Following this idea, website layouts and components should adapt to the size of the viewport where they are displayed.
With responsive images we refer to a similar concept applied to images. We let the browser know what images we have available, how big these images are or even what images we want to use based on the user viewport size.
The browser can then decide what is the best image to use not only based on the screen size and resolution, but also taking into account other aspects such as the available network.
In this blog post, we’ll see the different problems we might face when working with images and how to solve them.
Problem 1: Display resolution
Solution: Resolution switching
What is a Retina display and why we should take it into consideration from the moment we design a component?
Retina®️ displays were first used by Apple®️ when they released the iPhone 4. By doubling the pixel density of the iPhone 3, text looks sharper, and the eye really sees no pixel from a certain distance. That is why they call it retina displays or 2x displays. The device size is the same, but the number of pixels increases 4 times.
As raster images use discrete units (pixels), the more pixels we have, the better the image represents reality as visible below. The downside is that having more pixels means dealing with bigger images and that results in more data consumed, increased rendering times and additional latency.
We need to carefully design our responsive components and take 1x/2x displays into consideration when displaying images. Screens have the same width and height in inches, but since we now have 4 pixels for each regular pixel, we need to quadruple the number of pixels in order to fill the whole screen (we double the pixels on each axis).
In other words, a 320px image might cover the whole screen in a 1x display but only a quarter of the screen on a 2x display.
When we use small images to cover bigger areas, the rendered image becomes pixelated and the entire user experience might be affected. This happens when we use the same image on both 1x and 2x displays.
To avoid this problem, we can inform the browser that we have two image files available:
- One file for 1x displays (regular)
- One file for 2x displays (retina) doubling width and height
For example, a 320x320px image rendered on a 1x display will need a complementary 640x640px version for 2x displays.
The term resolution switching relates to declaring several image files for different screen resolutions but using the same size on screen so that the browser can pick up the most suitable one, avoiding blurred/pixelated images. It will consume more bandwidth for 2x displays, but the image will look sharp on the retina screen.
Tip: When showing raster images, we should always let the browser know what image to use for 2x displays. Otherwise, images will be pixelated.
Problem 2: A responsive component uses one image size only
Solution: Set up at least one image per component breakpoint when it makes sense.
Why is this tiny image taking so long to load?
Another image related problem happens when we want to use only one image with a specific size for a responsive component. Imagine you have a component that uses cards to display properties.
The number of cards change based on different breakpoints set up to adapt the component to multiple screen sizes:
As you can see, this component is responsive. It has different layouts and adapts to screen size for a better user experience. We’ll need to implement this component to take into account images of different sizes.
Sometimes components are designed for several screen sizes, but the implementation only uses one image size, maybe two based on whether the device is a mobile phone.
If we only provide images based on the device type, we will not give the user a good experience:
- We might end up downloading huge images to be displayed in small cards, we are forcing the user to wait until the images are fetched.
- Fetching small images that get rendered pixelated because the browser has to stretch them to cover a bigger area.
Imagine we use the next image to cover the 3 designs described above:
Let’s see the impact of using only that image for all mobile, tablet and desktop.
Mobile
For mobile sized screens we need to stretch the original image. We are saving some bandwidth, but the cost is that we will display a pixelated image.
Tablet
The image will need to stretch or expand depending on how we want the image to fit. In any case, it will look pixelated or blurry.
Desktop
The image will resize massively in this scenario. The image won’t get pixelated, but instead of this 9.9KB image we could have used another one with the right 112x58px size (about 2.6KB). That is an 84% improvement on the size of the requested image.
You can see the benefit of using the right size when it comes to images, especially when they are used in components like carousels or grids.
The solution is to consider and provide images based on the biggest image needed per breakpoint. That will require some calculations taking margins and paddings into consideration. We’ll review this in a following blog post.
Tip: When working with responsive components, ensure that images have been set up to fit the designed user experience. Otherwise, images will be pixelated or loading times will increase.
Problem 3: The image is cropped and has no meaning for the user
Solution: Design different images based on the component size
This is a very common scenario that happens when we have a responsive component:
- Using different aspect ratios based on the screen size.
- Using the same image for all of them.
When an image is cropped, we might lose control of what is rendered and the result might have a negative impact on users:
Another common mistake it to use a picture with an important and unique focus area that is likely to be cropped out.
This problem can be solved by creating several versions of our artwork, adapting the content to the different aspect ratios used on a responsive component.
Whilst this is a bit tedious and can be managed for components using static images, this solution does not scale very well for images fetched dynamically.
Some CDNs are incorporating features to combine AI to detect objects, people or even faces and auto crop the image centering these elements in the resulting image.
Tip: When working with images presenting different aspect ratios based on breakpoints, ensure that you provide images with the desired elements on the image.
Tip: Explore your CDN features to check if they provide options to detect and focus elements on the cropped image.
Conclusion
In this blogpost we have described how to use resolution switching to display different images for regular and Retina displays.
Moreover, we have covered that fetching the most suitable image for a specific rendering area can improve bandwidth usage, latency and rendering times.
Lastly, we discussed art direction and how providing different versions of an image based on the provided responsive designs can help us to keep focus on what really matters in the image.
References
- [1] http://alistapart.com/article/responsive-web-design
- https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
- https://developers.google.com/web/fundamentals/design-and-ux/responsive/images
Graphics in this post were constructed by the author using Adobe Stock images under Enterprise license and Pexels images under Creative Commons Zero license.