RFC: Responsive Images

##Motivation
Responsive images are arguably something every modern website needs and should be supported by frameworks like Flow (and Neos.Media in particular) in a convenient way.

##Status Quo
It is currently possible to manually define source sets and sizes in Fluid or Fusion using {media:uri.image(image: image, maximumWidth:width)} etc. Automated or reusable declarations have to be implemented by the integrator.
##Improvements
I suggest that Neos.Media should provide a dedicated API for rendering responsive images via configuration, Eel and View Helpers for Fusion and Fluid enthusiasts.
##Building Blocks
The most basic element in all of this are the already present ThumbnailPreset definitions via configuration. These can then be grouped into SourceSetPreset objects, with one of them being the preset being used for the fallback src attribute:

Neos:
  Media:
    sourceSetPresets:
      Stage:
        sourcePreset: 'My.Package:1280'
        thumbnailPresets:
          'My.Package:412': true
          'My.Package:600': true
          'My.Package:800': true
          'My.Package:1024': true
          'My.Package:1280': true
          'My.Package:1680': true
          'My.Package:2048': true
          'My.Package:2560': true

These again can then be grouped with a sizes definition to form a ResponsiveImagePreset:

Neos:
  Media:
    responsiveImagePresets:
      Stage:
        sourceSetPreset: Stage
        sizes: '(max-width: 1279px) 100vw, 1280px'
```
Together with such a `ResponsiveImagePreset`, any Asset may be handed over to the respective helper which returns a raw (or rendererd) `ResponsiveImage` object with the capabilities to render the final `src` and `srcSet` attributes required in the final HTML output, regardless of Fusion or Fluid being used.

##Further Steps
This is already implemented and can - once I change a few namespaces - be PRed into Neos.Media. I'd like to hear your thoughts and suggestions first, though :)
1 Like

I recently (well a few weeks ago) reworked our responsive image solution from Fluid / Fusion to an Atomic Fusion approach, so I’m pretty much into the topic.

The crucial part for us was to have a Fusion context capturing the “currently available width” for all breakpoints of interest (that might differ per project). So we introduced a few helpers and objects to do the actual calculation if images are nested e.g. in multi-columns. The one thing where we needed a new Fusion object was an asset helper that returns the URL, width and height of a thumbnail. With that you can do a lot of interesting calculations.

I can post the code if there’s interest because I think it’s pretty much feature complete (at least for our cases).

2 Likes

We also have already implemented a responsive images solution and I like to share my insights for a Neos internal solution.

From my POV this topic is more complex than just the rendering of an image in different sizes. The size of an responsive image depends on the surrounding content and the given device/breakpoint. So there are three topics to take care about:

  • Grid
    How many columns are in the row (multi column)? How width is an column? Is it nested within another row/column?
  • Breakpoints
    The grid is not fix, it differs for the different breakpoints (e.g 4 cols(25%/25%/25%/25%) on desktop, 2x2 cols(50%/50%) on tablets. And also more advanced use cases (e.g 3 cols(25%/25%/50%) on desktop, 2 cols(50%/50%) and 1 col (100%) on tablet.´, etc.
  • Image
    Based on the information of the grid and the breakpoints (and some configuration e.g. width of layout, col margins) you can calculate the image size of each breakpoint and render the fitting image.

Decisions to make

  • CSS Framework
    This is also an CSS topic, which handles the grid layout/rendering and it is responsible for the width of each column. We have implemented out solution based on bootsrap grid, but the question is, if Neos likes to bind themself to ONE css framework. Also other css frameworks providing grid solutions.

  • CSS Styles
    Also some image related styles have to been set with css like (width: 100%, etc). May Neos be responsible for the needed CSS, too? Is it provided in css, sass, less, …?

  • Responsive image rendering
    There are currently two common ways to render responsive images with small differences: picture-tag or image-srcset (see: https://responsiveimages.org/) We had decided to use picture-tag, but image-srcset should also be suitable.