Responsive Images in Sitecore

By default, when you add an image to a page in Sitecore using the <sc:Image > control it will render height and width attributes on the resulting html. These are based on the images dimensions or any height and width properties you may have set server side.

The benefit of doing this is that when the browser renders the page, it already knows what space the image will take up before the image has loaded. This reduces the number of repaints the browser has to make and ultimately speeds up the page rendering time. If the height and width weren't specified then a repaint would happen after the image was loaded as the size would now be known.

However this can cause an issue when you are producing a responsive site that changes its layout based on the size of a device or width of a browser window. Because responsive design is done though CSS media tags the server does not know what the height and width of the image will be, unfortunately there's also no built in way to tell Sitecore to stop rendering the height and width tags. Not very good when you want to size your image to 100% width of an area that can change size.

The solution is to create a Pipeline. Pipelines are Sitecore's way of enabling you change how Sitecore works and their not overly complex to implement.

To create a pipeline that will affect the way an Image field is rendered your first need to create a GetImageFieldValueResponsive class as follows. The name of the class can be anything you want but I've called it GetImageFieldValueResponsive as it will be called after Sitecores GetImageFieldValue class.

1namespace SitecoreCustomization.Pipelines.RenderField
2{
3 public class GetImageFieldValueResponsive
4 {
5 public void Process(RenderFieldArgs args)
6 {
7 if (args.FieldTypeKey != "image")
8 return;
9 if (args.Parameters.ContainsKey("responsive"))
10 {
11 string imageTag = args.Result.FirstPart;
12 imageTag = Regex.Replace(imageTag, @"(&lt;img[^&gt;]*?)\s+height\s*=\s*\S+", "$1", RegexOptions.IgnoreCase);
13 imageTag = Regex.Replace(imageTag, @"(&lt;img[^&gt;]*?)\s+width\s*=\s*\S+", "$1", RegexOptions.IgnoreCase);
14 imageTag = Regex.Replace(imageTag, @"(&lt;img[^&gt;]*?)\s+responsive\s*=\s*\S+", "$1", RegexOptions.IgnoreCase);
15 args.Result.FirstPart = imageTag;
16
17 }
18 }
19 }
20}

The process function in the class is what will get called as the control is rendered. First it will check that the field type is an image and then will look to see if there is a parameter called responsive. This will allow us to control when Sitecore should output height and width tags and when it shouldn't. Lastly some Regex is used to remove the height, width and responsive properties from the image tag that will already have been generated by this point.

Next we need to tell Sitecore to start using this pipeline. We do this by creating a RenderField.config file and placing it in the App_Config\Include folder of your Sitecore solution.

1<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
2 <sitecore>
3 <pipelines>
4 <renderField>
5 <processor
6 patch:after="*[@type='Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel']"
7 type="SitecoreCustomization.Pipelines.RenderField.GetImageFieldValueResponsive, DLLNameOfWhereYouCreatedTheClass"/>
8 </renderField>
9 </pipelines>
10 </sitecore>
11</configuration>

Lastly your control will need to have an attribute to say it should be responsive. For an xslt rendering your code will look like this:

1<sc:image field="Image" responsive="1" />

And for an ascx sublayout it will look like this:

1<sc:Image runat="server" Field="Image" Parameters="responsive=1" />