Images, reactiveness, resizing and ratio

Hello all,

For Loading... I am trying to untangle the topic of image resizing while respecting the preserving the following constraint:

  • reactiveness (i.e., images should resize to fit the available width on small screens)
  • user should be able to resize images, possibly with and image ratio (i.e., width/height) that does not match the original ratio of the image
  • optimized image (the returned image should match the space allocated to it in the page, i.e., no need to returned a 2000x2000px image if it will be displayed as 200x200px)

Technical notes

(discussed in the Github PR)

  • When the two dimensions are provided to the image downloader, the image is now scaled server side (it was previously scaled down to fit the width x height box)
  • Images have max-width: 100%; and height:auto applied for reactiveness (i.e., the image is never larger than the available width, and the height follows)
  • In edit mode, the size is not passed server side so the image ratio is not respected (but it is once the document is saved and displayed)

Issues

  • if the width is larger than the original width of the image, the height is ignored
  • if the height is set but is larger than the original image, it is ignored
  • if only one of the dimension is larger than the original image, is is replaced by the dimension of the original image, and the image is scaled to an odd ratio

Proposals

Aspect 1: edit/view consistency

This can be done by passing the dimensions to the image download endpoint in edit mode (this is what’s done in view mode).
This part will not fix anything strictly speaking, but the user will hit the same bugs in edit and view mode, allowing to anticipate them earlier.

Aspect 2: ratio and outscaling

We have explored several options with @MichaelHamann and @mflorea (see the Github PR discussions), but so far we did not found a suitable solution for all cases (or quite complex ones).
I propose to improve the image dialog UI so that, whenever the defined width/height is larger than the dimensions of the image, a warning message explaining the limitations is presented to the user (i.e., the aspect ratio is not respected).
This message would be removed as soon as a suitable solution is found for this issue.

Some notes:

  • scaling should not be performed server side as server side resizing is only meant to optimizing image size (a keepAspectRatio parameter, defaulting to false exists though)
  • that leaves us with css based definition of image size and scale

I’ll update this thread with progress as they happen.
For now, WDYT of adding a warning and creating a separate issue for image resizing and scaling improvements?

Some more thoughts (primarily for the general direction of image size handling, not sure we should do something about this now):

  • We should render a width and height on all images to avoid layout shift when the page is loaded.
  • To me, this means that ultimately the width and height attribute in XWiki syntax should not be equivalent to the width and height attribute in HTML. Width and height attribute in HTML should always mirror the server-side resizing.

More concretely:

For editing, I think the moment a user grabs the image resize handle in CKEditor, we should disable reactive resizing such that the user can resize the image to an arbitrary size. After the user finished resizing, the new dimensions can then be requested from the server and reactive resizing can be re-enabled. This could be done by either temporarily setting width and height using CSS or by adding a class that is targeted by the CSS.

I’m also fine with adding a warning when the size is larger than the original, it could also mention that this is bad for the quality. We could additionally add an option to disable reactive resizing on a per-image basis (e.g., by adding a CSS class or data attribute) which would fix this issue.

A real fix would be to explicitly set the aspect ratio using CSS whenever it deviates from the original aspect ratio. From my tests this works when at least the width has been set to the desired width.