By using the picture element together with ImageProcessor, you can create a robust solution for responsive images. With this solution you can very quickly make sure that you at least don’t serve way too big images. Once that is done, you can add more image sizes and fine tune the media queries, to further optimize the images on your site.
ImageProcessor is a great, free, library for image manipulation. You can use it with any Asp.Net Framework site. It’s bundled with Umbraco, and lucky for us Vincent Baaij recently made it possible to use ImageProcessor together with Episerver.
When using the picture element you let the browser decide what image to use depending on viewport width, device pixel ratio and even network speed
My solution consists of two parts (I’m assuming ImageProcessor nugets are already added to your solution):
The image types
An image type is an image on a specific place on your site. Examples of image types: “Top hero image”, “Contact person image”, “Image gallery thumbnail”.
Instances of the ImageType class contains all the information needed to render the picture element for the specific image type. E.g. the different widths of the Top hero image at specific viewport widths
The “Picture” html helper
Takes care of the actual rendering of the picture-element and its sub-element. The html-helper takes an ImageType and an image-url as input parameters.
To make it easier to test that everything works as expected, I added the appsetting “ImageProcessorDebug” in web.config. When that value is true, the width of the image will be shown in the image (you need to enable “watermark” in processing.config for that to work).
How to use the Picture helper
If we want to use responsive images for the teasers on the Alloy site we would change this:
<div @html.editattributes(x=> x.Image)> <imgsrc="@Url.ContentUrl(Model.Image)" /></div>
<div @html.editattributes(x=> x.Image)> @Html.Picture(Url.ContentUrl(Model.Image), ImageTypes.Teaser)</div>
The resulting markup would be
<picture> <sourcesizes="(max-width: 980px) calc((100vw - 40px)), (max-width: 1200px) 298px, 368px, " srcset="/globalassets/alloy-plan/alloyplan.png?width=298 298w, /globalassets/alloy-plan/alloyplan.png?width=375 375w, /globalassets/alloy-plan/alloyplan.png?width=500 500w, /globalassets/alloy-plan/alloyplan.png?width=750 750w, /globalassets/alloy-plan/alloyplan.png?width=980 980w, /globalassets/alloy-plan/alloyplan.png?width=1024 1024w, /globalassets/alloy-plan/alloyplan.png?width=1400 1400w, /globalassets/alloy-plan/alloyplan.png?width=1500 1500w, "> <imgsrc="/globalassets/alloy-plan/alloyplan.png?width=750"> </picture>
Below you can see how different images are selected by Firefox when resizing the browser window.
When using a mobile with a higher device pixel ratio, a higher resolution image will be selected by the browser.
…and when you flip the phone, an even higher resolution image will be selected
Image type “Art direction”
This solution could be extended to support simple “art direction”. Maybe your full-width Hero image has lesser height on really wide screens? No problem, you could extend the image type to also specify the height of the image.
Happy coding! 🙂
At time of writing I was using Episerver 184.108.40.206