One Size Fits All? Unfortunately not.


Responsive web design

Previously, an image resolution had to be enough for different end devices – a perpetual search for the compromise between high image details 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 fluently adapted to the different formats – but still always the same size image loaded – that must be better.

The solution

Image sizes depending on the screen resolution

In order to load images for different screen sizes, there is now the possibility, to submit – depending on the screen size of the browser – different image resolutions – it then loads the image as appropriate to the resolution:

<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 indicates that the original image.png is 1500 pixels wide, the image-1000×500.png is 1000 pixels, 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 with this information, the width of the image is compared with the width of the screen resolution – so at least as much as possible loaded an image that is not larger than the screen width. For a header image in screen width completely sufficient.

challenge

Image sizes depending on 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.

The solution

Set slot width

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 correspond exactly to those in our responsive design – but also use meaningful 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’s technically feasible to give the browser the right image size – so why not do that 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 even know the slot width at this point: hitherto the HTML is read by the browser, but not the styles (CSS) – nevertheless the pictures should be requested in the correct sizes, even before the browser knows how big they should actually be displayed later.

Since WordPress or Gutenberg creates the HTML markup, they must already determine the width of the images 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 carried out by the browser is a performance advantage: about 20% percent page layout should be faster – theoretically, because if too large images are loaded, the performance advantage is quickly gone.

Gutenberg

Responsive incomplete

Gutenberg effectively avoids the fact that hardly an image linked to the image block is much larger than the screen size – 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 greater – 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 it is only loaded if the browser window is a maximum of 250 pixels wide.

Although the image block allows the selection of image size in the block settings – but that’s not responsive. After all, in this selection is not known which terminal visited the page and thus what image size would have been correct.

perspective

A solution is being worked on

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 for each image, media-sizes would have to be calculated, depending on the layout, so if it is 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.

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