Matthias Bathke Avatar

from

Reading time: 6 minutes

Gutenberg and responsive image sizes

There are various web techniques that ensure that current images are loaded in the right resolutions – Gutenberg partially supports them – an inventory.

In the past, one image resolution had to suffice for different end devices – a perpetual search for the compromise between high image detail and high performance. Example:

<img src="image.png">Code language: HTML, XML (xml)

It is obvious that an image file can not map all resolution formats, but always only one. 163/5000 Whether retina smartphone, landscape or portrait, tablet, Ultrabook, desktop monitor or 4k TV: There are countless different devices and thus resolutions.

In Responsive Design, the layout of the website is smoothly adapted to the different formats – and yet an image of the same size is always loaded – that has to work better.


Image sizes depending on the screen resolution

The solution

In order to load images for different screen sizes, there is now the possibility to send different image resolutions to the browser depending on the screen size – it then loads the image matching the resolution if possible:

<img src="image.png" srcset="image.png 1500w, image-1000x500.png 1000w, image-500x250.png 500w, image-250x125.png 250w">Code language: HTML, XML (xml)

The srcset attribute lists additional alternative sizes of the image. In this example, it specifies that the original image.png is 1500 pixels wide, the image-1000×500.png is 1000 pixels wide, and so on. The browser knows therefore already before the loading of the pictures, in which different resolutions they are present. If we leave it at this, the width of the image is matched with the width of the screen resolution – so at least an image is loaded that is not larger than the screen width, if possible. For a header image in screen width completely sufficient.

Image sizes depending on slot width

The next problem: slot width

Unfortunately, the screen resolution alone often does not help us as a threshold. This way works basically only if there are no different layouts, e.g. all images always have the same width and they only have to adapt to the screen resolution.

On many websites images are designed differently. A sidebar might be active on some subpages, but not on others. Images could take the full screen width or break the width of the content (Wide Width). But even if images are not larger than the width of the body text, they can be structured in columns.

column width

Especially the use of columns in the layout of the content complicates everything: In desktop resolution, the columns are displayed next to each other, so they each have a smaller width than on Mobil, where they break and are displayed in full width among each other.

Flowing text width

The images in the above example are therefore larger on mobile and so here on mobile a higher-resolution image should be loaded, on the desktop is a smaller version.

With desktop resolution, an image has a width of 172 pixels due to the column view.
With mobile resolution, the columns are displayed one below the other, giving them a width of 335 pixels.

Set slot width

The solution: slot width dependent sizes

So, if we know how wide the individual slots will be in which images should be displayed, we can set them using the sizes attribute:

The sizes attribute allows Media-Queries to be used and thresholds set. These define the size of individual slots that will take the pictures under the resolutions. The slot size can be set to units such as viewport (vw), pixels (px) or em (relative size), but not percent.

<img src="image.png" srcset="image.png 1500w, image-1000x500.png 1000w, image-500x250.png 500w, image-250x125.png 250w" sizes="(max-width: 250px) 250px,(max-width: 500px) 500px,(max-width: 1000px) 1000px, 1500px">Code language: HTML, XML (xml)

IMG sizes explained

Based on the code shown, one recognizes the following:

4 images are available as resources (srcset).

  • 1500 pixels wide
  • 1000 pixels wide
  • 500 pixels wide
  • 250 pixels wide

In addition, it is determined for three different resolution thresholds (sizes) which image should be loaded:

  • Screen width up to 250 pixels: Load 250 pixels image
  • Screen width up to 500 pixels: Load 500 pixels image
  • Screen width up to 1000 pixels: Load 1000 pixels image
  • Otherwise, the original image is loaded again, so the 1500 pixels wide image

However, this does not solve the slot problem, because the above behavior would also be the default behavior of the browser, if only srcset without sizes had been defined. In the desktop resolution, smaller images would eventually be enough because of the column view. An optimized loading could look like this:

Let’s make it even more complex

Calculate slot widths

The breakpoints in the sizes attribute should not only exactly match those in our Responsive design – but also use sensible image sizes. So if our web design should break to mobile at a maximum of 1000 pixels wide, we would have to set for the desktop layout (> 1000 pixels screen width) when the image should not be loaded with the full 1500 pixels. So unless it’s a full-width image, we’ll need to adjust the value for Desktop. We now need to know which layout features could affect the width of the image. The decision path using the example of the columns:

  • The picture does not take up full width
  • The picture does not take a wide width
  • The image is within the content area and therefore has a maximum width
  • The layout has no sidebar and therefore the width of the content area has not changed
  • The image is in a column and therefore does not occupy the full width of the content area
  • There are 3 columns, so the image should be one-third as wide as the width of the content area.
  • Possibly still deduction of margins within the columns
<img src="image.png" srcset="image.png 1500w, image-1000x500.png 1000w, image-500x250.png 500w, image-300x150.png 300w, image-250x125.png 250w" sizes="(max-width: 250px) 250px,(max-width: 500px) 500px,(max-width: 1000px) 1000px, 300px">Code language: HTML, XML (xml)

So the new thresholds would be:

  • Screen width up to 250 pixels: Load 250 pixels image
  • Screen width up to 500 pixels: Load 500 pixels image
  • Screen width up to 1000 pixels: Load 1000 pixels image
  • If the screen width exceeds 1000 pixels, the desktop layout is displayed, and thus the column view. The content area then has a maximum width of 1000 pixels, so that with three columns, the images should be loaded in a resolution of 300 pixels. In addition, we have set up an additional level for the srcset, because we often use a three-column layout and therefore want to deliver the intermediate level accurately.

So it is technically feasible to send the correct image size to the browser – then why is this not (yet) done in Gutenberg?

The next hurdle

The whole please automatically

So far, the WordPress Gutenberg team has not found a final solution for this: How is the slot width calculated for each image? The best would be the browsers themselves: As soon as a website is rendered, the browser knows how wide the slot is and could choose from the images defined under srcset.

Unfortunately, the browsers do not know the slot width at this point: Up to this point, the HTML is read by the browser, but not yet the styles (CSS) – nevertheless, the images should already be requested in the correct sizes, even before the browser knows how large they should actually be displayed later.

So, since WordPress or Gutenberg creates the HTML markup, they already have to determine what width the images should have depending on the media breakpoint – depending on the layout factors mentioned.

The reason why the slot width calculation for the delivery of the images is not done by the browsers is a performance advantage: About 20% percent the page load should be faster – theoretically, because if much too large images are loaded, the performance advantage is quickly gone.

Responsive incomplete

Stand in WordPress Block Editor

Gutenberg currently effectively avoids the fact that hardly any image included via the image block is much larger than the screen size – but that’s about it. The following screenshot shows that you can easily load an image with three columns in the desktop resolution, which can be too large by a factor of ten.

If additional columns are used, the discrepancy becomes even larger – postage stamp-sized images are loaded in full resolution. In this example, the approximately 1500 pixels original. A version with a width of 250 pixels would also be available – but this is only loaded if the browser window is a maximum of 250 pixels wide.

Although the image block allows the selection of the image size in the block settings – but exactly this is not Responsive, after all, with this selection is not known which terminal visits the page and thus what image size would have been correct.

A solution is being worked on

perspective

If you would like to get involved in solving the problem, one of the main discussions can be found on GitHub, but there are many more tickets that address the Responsive Media Sizes problem in Gutenberg. These are currently the biggest hurdles:

  • The Gutenberg editor usually has a different width than the frontend, so you can not calculate the sizes attribute in the editor via Javascript.
  • Alternatively, when saving a post, media-sizes would have to be calculated for each image, depending on the layout, i.e. whether Full Width / Wide Width / Content Width / Content Width – Sidebar / Column Width and for Column Width also the number of columns or their width. Columns could be nested with the Groups block.
  • The developers are therefore trying to find the most general basis for calculation that harmonises with millions of WordPress websites that use the Gutenberg editor.

Interim solution: insert e.g. with Imagify a maximum width for all pictures fixed, manually for each picture individually goes in the Mediathek. To prevent at least the worst, e.g. 4,000 pixels wide images.

Update: Since WordPress v5.3, large images are automatically scaled down when uploaded. However, due to a bug, only JPG images and not PNG images, which makes this feature unfortunately unreliable.

If you are interested in the topic and want to immerse yourself even more deeply: