23 November 2015

Responsive images for Blogger

With mobile devices spreading everywhere and diversifying into many sizes, from small smartphone screens to large hi-res TVs, web development faced an unexpected problem: how to adapt design practices for this growing array of gadgets, especially traditionally fixed elements like images and video. After long deliberations, the agreed solution was the responsive images specification. It’s currently fully adopted by Google Chrome (including Opera) and Firefox and Microsoft Edge is rolling out an update with full support. Safari, unfortunately, offers only partial support for the latest specification.

Current support for the responsive images specification
Current support for the responsive images specification via Caniuse

There are many online resources dedicated to responsive images, such as “The anatomy of responsive images” by Jake Archibald, and the truth is, they’re needed. For reasons explained at length in this video and accompanying slides, responsive images require not only extra image files of different dimensions, but also extra markup to guide the browser in choosing the best size and resolution for the current device. The original attributes of the <img> tag (src, the image source, which now acts as fallback for older browsers, and the alt description) are expanded with two new ones: srcset defines a list of image files of different dimensions and sizes offers a rough indication of the page layout. Using this information, the browser will select an image file from the srcset list before starting to download image resources; as a result, pages load significantly faster on smaller screens without sacrificing high resolution on large displays.

Amaze your friends, confound your enemies! Oh, and save bandwidth and speed up your site by sending the correctly-sized images for the device with HTML’s new responsive images capabilities. Bruce proposed the new element in 2011, and it’s just gone live in Opera and Chrome, and coming soon in Firefox, so learn all about it now and put use the techniques tomorrow.

To make matters more complicated, srcset accepts two different methods of specifying the images, one based on screen resolution (the x descriptor), the other on image width. As mentioned before, Safari, both desktop and mobile, (and until recently Edge as well) supports only the first variant, so you need to take this into consideration when using responsive images. As I worked on my solution for Blogger, I chose to ignore the resolution-based aspect of the spec, because I think it’s poorly adapted to the variety of devices on the market and for responsive design. Because you need to specify a lot of information for each image directly in the HTML source as opposed to global CSS, it’s better to use a future-proof solution, otherwise every time a new device resolution becomes popular, you will need to go back and update old posts. With w descriptors on the other hand, the browser will do the calculation, selecting a larger image when it encounters a higher resolution display.

As the years passed, Blogger was updated less and less frequently – though there are some reasons for hope given that it’s at least getting experimental HTTPS support – but an old feature is surprisingly useful for implementing responsive images. When you upload image files to Blogger, Picasa, or more recently Google Photos, the files can be accessed at virtually any size by changing a part of the URL: a /s1000/example.jpg image will be 1000px on its largest side; use /s250/ instead and Google serves a 250px image; and so on. This works perfectly for responsive images, since the user doesn’t need to spend time resizing images before uploading; instead you simply upload images at the higher resolution (in order to avoid blurriness caused by upscaling) and retrieve the desired sizes by changing the URLs.

As I was writing this article, I discovered two other prefixes supported by Blogger: /w followed by a dimension controls image width specifically and /h the height, so /w1000/ will generate a 1000px-wide image, while /h1000/ a 1000px-tall image. I don’t remember reading about these two anywhere before, so be a little cautious when using this feature; if it’s not official it may be retired at some point. The srcset spec only works with image widths currently, so simply using /s is fine for landscape and square images, where the largest side corresponds to the width.

With this problem out of the way, the next step was to automate the process of generating the image widths and URLs. For this purpose, I set up an Excel file where I input the Blogger image URL and its width; the formulas then generates the correct srcset code. This could probably be done online with JavaScript as well, but I’m much more comfortable with text processing in Excel than in JavaScript. For simplicity, I chose to have three image sizes, each 1.6x smaller than the previous.

My sheet for generating srcset. Feel free to download and use it

As for the sizes attribute, it doesn’t need to be that strict and can be approximated based on the general layout of the page. If you use a responsive design, you need to integrate rough breakpoints in the sizes attribute. In my case, I chose a 35em (about 550px) limit between mobile and desktop designs – even though these are not nearly implemented yet on my blog. Also, I generally use two image positions, either on the side or full center, spanning the width of the article. I approximated side images to 25% of the viewport width and full images to 75%, because images shouldn’t extend over the sidebar. So the full attribute for an article-spanning image is sizes="(min-width: 35em) 75vw, 100vw", which the browser interprets as: “on devices larger than 35em wide choose the image closest to 75vw, on smaller devices the image closest to 100vw”.

So my current workflow for responsive images on Blogger is as follows:

  • Write the post as usual in Windows Live Writer and upload as draft to Blogger;
  • Upload any large images from Blogger’s online interface in HTML editing mode (‘large’ meaning usually wider than 750px, it doesn’t make much sense to use the extra markup for smaller images). This has the added benefit of generating URLs on the blogspot.com domain, saving a DNS lookup during page load;
  • Copy the URL from Blogger’s generated code into my Excel file. If you select ‘Original size’ during upload, Blogger will assign a default width of 1600 to the image, regardless of its actual width;
  • Input the image file original width into the next cell. The formulas will then generate two smaller sizes and the corresponding image URLs;
  • Copy the final srcset code into the HTML code of the article on Blogger, along with the correct sizes declaration, depending on whether the image will be positioned on the side or centrally;
  • Also replace the original src of the image with the URL of the smallest size generated in the process. Since this src will be rendered by browsers that don’t understand the extra code, including mobile Safari and older versions of Android, it’s a good compromise to serve the smallest and fastest image to older mobile browsers.

You may have noticed that src includes the HTTP protocol, while srcset uses relative URLs. That is another compromise, this time for social sharing, because in my experience Facebook’s OpenGraph ignores images using either relative or secure URLs. On the other hand, OpenGraph doesn’t yet understand srcset, so it’s safe to use a protocol-less URL or the HTTPS version there. Since modern browsers with support with responsive images ignore src and go straight to srcset to retrieve an image to render, this should prevent mixed-content warnings on secure sites.

1 comment: