Programming

Juan Pablo Balarini • 22 MAY 2023

Rails 7.1 adds support for responsive images via a new picture_tag helper

post cover picture

I'm excited to announce that the Ruby on Rails team has accepted a pull request that I recently submitted, which introduces the new picture_tag helper to simplify the usage of the <picture> HTML element in Rails applications. In this blog post, I'll delve into the process of creating this feature, my motivations, challenges, and a detailed step-by-step guide to help you incorporate it in your Ruby on Rails projects.

 

Background and motivation: why create a picture_tag?

It all stems from necessity: we wanted to use the HTML <picture> tag in our website for responsive images, specifically for art direction, but we found that Rails did not have built-in support for it. This led us to create a gem to fulfill this need and share the concept in a RailsConf talk. Many attendees encouraged me to incorporate this feature into Rails, resulting in the creation of this pull request.

The <picture> tag is a robust replacement for the <img> tag as it supports resolution switching, art direction, and image support fallback, unlike the latter which only supports resolution switching. This makes the picture_tag helper a great addition to Rails.

 

How to use picture_tag: step by step guide

The picture_tag helper allows you to pass either a single element (String), multiple elements (an Array), or a Block for complete control over what's generated. All properties passed to the helper will be applied to the <picture> tag. If you need to pass properties to the <img> tag, you can do it inside the :image key.

The <picture> tag requires an <img> tag (unlike audio_tag or video_tag, which only require sources), so the last element you provide will be used as the source for the <img> tag.

Here are some usage examples:

1. Basic usage: using a single source

<%= picture_tag("picture.webp") %>

this will generate:

<picture>
    <img src="/images/picture.webp" />
</picture>

2. Intermediate usage: using multiple sources

<%= picture_tag("picture.webp", "picture.png", class: "mt-2", image: { alt: "Image", class: "responsive-img" }) %>

This will generate:

<picture class="mt-2">
    <source srcset="/images/picture.webp" />
    <source srcset="/images/picture.png" />
    <img alt="Image" class="responsive-img" src="/images/picture.png" />
</picture>

3. Advanced usage: full control via a block

<%= picture_tag(class: "my-class") do %>
    <%= tag(:source, srcset: image_path("picture.webp")) %>
    <%= tag(:source, srcset: image_path("picture.png")) %>
    <%= image_tag("picture.png", alt: "Image") %>
<% end %>

This will generate:

<picture class="my-class">
    <source srcset="/images/picture.webp" />
    <source srcset="/images/picture.png" />
    <img alt="Image" src="/images/picture.png" />
</picture>

It's fantastic to see this new functionality added to Rails, and we hope that it will be beneficial to many Rails projects. Now it's much easier than ever to incorporate responsive images into a Rails applications. The community has always been about making life easier for developers, and we believe that this new helper is a step in the right direction. Happy coding!

The pull request can be viewed here

Stay updated!

project background