Lawrence Murray on 30 October 2022
The Jekyll plugin described here is now available, if you just want to get it installed.
A responsive design adapts to display size to improve the user experience. An example is a grid layout that increases the number of columns with the width of the screen, from one on a narrow mobile device, to several on a wide screen display. A responsive design is made up of responsive design elements, among them responsive images, which help to:
While the second motivation makes sense for all image formats, the former only makes sense for raster formats such as PNG and JPEG. Vector formats such as SVG are already responsive, in that they scale up and down without loss in clarity or change in file size.
Responsive images are enabled by two attributes of the HTML
srcset, providing a list of available image variants and their widths, and
sizesproviding a list of context-specific hints.
img element should also provide the common
height attributes. Putting them all together, it should look something like this:
srcset attribute provides three image variants:
example-w256.jpgof width 256 pixels,
example-w512.jpgof width 512 pixels, and
example.jpgof width 1024 pixels.
sizes attribute provides guidance as to the context in which the image appears:
575px) then there is one column (
100vwi.e. 100% of viewport width),
767px) then there are two columns (
50vwi.e. 50% of viewport width),
991px) then there are three columns (
This suggests that the image will appear as part of a one to four column layout, depending on display width.
srcset is achievable; we do so here. Automating
sizes is much more difficult as its value depends on the context in which the image appears; we do not attempt to do so here.
The particular breakpoints chosen above are derived from those in Bootstrap.
ImageMagick is a command-line tool that can query and modify images in a wide variety of formats. We use its
convert tool for resizing images:
Here, we convert
example-256w.jpg, stripping meta data (
-strip) setting the quality (JPEG compression in this case) to 30, and resizing to a width of 256 pixels (the height will be scaled proportionally).
We also use ImageMagick’s
identify tool to obtain the widths and heights of images:
-ping option avoids consuming the entire file to obtain this information. The
-format option gives the output format, in this case the width and height separated by a comma (
'%w,%h'). The output will be e.g.
ImageMagick has numerous libraries available for various programming languages. However, we will use the command-line interface directly to minimize dependencies, given that our needs are simple.
We now develop a Jekyll plugin that automates image resizing for a given set of widths. For convenience, it also provides filters to set
Add the following to the site’s
This configures the widths of resized images and their quality. The choice of
widths should cover the typical sizes of images as they appear on the site. The choice of quality (between 0 and 100) is a trade-off between file size (lower at lower quality) and clarity (higher at higher quality). It could be tuned by eye. Low quality can be very satisfactory with the prevalence of high definition displays.
For indii.org, where most images are photos, I find noticeable degradation in thumbnail quality at 20, but little at 30. That thumbnails link to original high-resolution images also permits the quality to be reduced. For
widthsvalues I iterated with PageSpeed Insights to assess performance, and settled on the above configuration.
The plugin requires ImageMagick. It is standard in Linux distributions and available through Homebrew on macOS. If not already, it can be installed with e.g.:
If you happen to be hosting with CloudFlare Pages, it is already installed.
Copy the Ruby code below to
The plugin provides three filters:
height. Each consumes an absolute path to an image (as it would appear in
src) and generates a value for the corresponding attribute. The intended usage is:
src must be an absolute path, i.e. beginning with
/, such as
/assets/example.jpg. This is necessary for the plugin to find the right file in your project.
With the plugin installed and one or more uses of the
height filters, you can build your site as normal, now with responsive images.
To test that responsive images are working, try:
_sitedirectory, or via your browser by right-clicking and selecting “View source”. Verify that the
heightattributes are set correctly.
256denotes the resized width.
height filters call ImageMagick’s
identity on demand, rather than for all image assets in a project. Caching is used to call
identity at most once per image per build, and
convert once per image per width, storing resized images in a subdirectory
_responsive/ for reuse in subsequent builds. Resized images in
_responsive/ are updated only if their original source image changes (detected using last modified times on files).
If you experience any issues with outdated images, or simply wish to clean up, remove the whole
_responsive/ directory and rebuild. You may also wish to do this if you change the
widths option in
height, expect additional build time of about one second per 100 images due to the overhead of launching
srcset for the first time, expect additional build time on the order of minutes as resized images are generated with
convert. Performance will improve drastically on subsequent builds because of the
With a combination of a plugin and ImageMagick, we can automate the addition of the
srcset attribute to
img elements for Jekyll sites, creating responsive images to minimize transfer time and optimize website performance.
A how-to and round-up of cloud service providers.
22 Nov 22
Zero-stride catch and a custom CUDA kernel.
16 Mar 23
Working or failing gracefully across Apostrophe, Kramdown, and Jekyll. No plugins required.
2 Nov 22
F. Ronquist, J. Kudlicka, V. Senderov, J. Borgström, N. Lartillot, D. Lundén, L.M. Murray, T.B. Schön, D. Broman