Responsive websites adapt the layout of their content to different screen sizes to retain its legibility and usability on today's various device types. Having responsive images is essential to reaching this goal because appropriately sized images not only contribute to the look and feel of web pages but also speed up their delivery and thus improve the visitors' user experience. Scrivito allows you to easily make the images on your website responsive.
We are going to use the
srcset HTML attribute to achieve this. Let's get started.
srcset attribute can be used as an optional extension to
img tags and lets us specify differently sized versions of an image. Browsers recognizing this attribute can then choose the image that fits best.
Scrivito has the ability to scale images on demand and also cache the versions produced (see Transforming Images for details). It also provides an easy-to-use mechanism for specifying the versions and sizes to make available to the browser.
srcset attribute requires a comma-separated list of URLs pointing to images and their respective widths. For example, if we wanted to offer three different versions of an image, we would specify the
srcset attribute like this:
Now, all that's missing are the scaled images.
As mentioned above, Scrivito is capable of producing differently sized versions of images. It doesn't simply scale images on-the-fly but caches them, so they are delivered faster and cause less server load. Take a look at the Rubydoc, if you want to see how to use the API in detail. We are only going to transform images with respect to their width, preserving their aspect ratio. An example:
To be able to easily apply image transformation to all images later on, we are first going to define a helper method that does this job. This helper transforms individual images and returns their respective URLs and widths required for
srcset. Create the file
app/helpers/srcset_helper.rb and add the following code to it:
We can call this helper method in any view in which an image is rendered, e.g. in the view of the image widget that comes with Scrivito.
Navigate to the view file of the image widget located at
app/views/image_widget/show.html.erb and add the
srcset list by using the
srcset_for method we just created.
Are we finished now? Almost. Since the helper method creates images with different widths, the browser won't know the width of the original image. Therefore, we need to specify a width in the application stylesheet in
app/assets/stylesheets/application.css.sass. Open this file and add the following line to it:
Image responsiveness should work with all new browsers. But what about older browser versions? Let's go ahead and see what we can do.
srcset attribute allows the browser to choose the image that fits best. But how does it know? Basically, the width of the browser window is used to determine the amount of space available for an image. In the future, additional criteria like the connection speed or traffic limits might come into play.
The method introduced above creates several scaled-down versions of your original image. This is sufficient for one-column layouts or header images occupying the full width of the window. With dynamic multi-column layouts, however, the browser needs to know the reduced width of the area available for an image to select the best fitting one from the
srcset list. For this, the
sizes HTML attribute is available.
sizes attribute can be applied to
img tags. It lets you specify fractional widths depending on one or several media queries:
The example above states that for all browser window widths equal to or larger than 992px (which is Bootstrap's breakpoint for desktops), the image should use 50% of the screen width. Otherwise, it uses 100% of the available width.
For example, in the case of a full HD display with a width of 1920 pixels, which exceeds 992px, the result will be 1920/2=960px. Hence, the browser will select from your
srcset list the image whose width comes closest to 960px.
Note that you can combine several media queries as a comma-separated list. The 100% fallback in the example above could be replaced with another media query to distinguish between smaller and tiny image areas, in case you need to handle three-column layouts, for example.
For every image, an individual pair of
sizes attributes can be specified. With Scrivito, the
sizes attribute can be calculated using the
container method of the widget.
Navigate to the image widget view file located at
app/views/image_widget/show.html.erb and add a
sizes specification that computes the relative image width using the not yet existing
To determine the width available for the image, its location in the DOM must be known. To get at this location, we can use the widget's
container method and provide it with the
column_size method we used in advance above.
If the parent widget is a column widget, we're done and return the percentage available for the image, depending on the column width. This is done by determining the percentage of the smallest possible column and multiply this value by the column's width.
If the image widget is directly contained in a
widgetlist attribute of a CMS object, the full width (100%) is returned. If the layout of your pages reduces the width available for the content (like a sidebar does), you might want to take account of this, too.
sizes attributes for all browsers.
Congratulations, you are finished! Your website now delivers images contained in image widgets responsively as a default.