Image Style serialization class vs data attribute

Hello all,

Following the discussion of Image Style serialization - #19 by mleduc, I’d like to open a vote.

So to summarize the problem, the goal is to agree on a way to represent the image styles and their configuration on images.

For a given image, the information to store are:

  • the image style id
  • if the image has a border
  • if the image has an alignment (none, start, end, center)
  • if the surrounding text should wrap the image

Those information should also be accessible in the generated html so that skins can define specific css styles according to the image style and its configuration

In addition, an image can have a caption. When rendered in html, an image with a caption is wrapped on a figure tag. While we might not do it in a first time, it is interesting to understand that we might like in the future to also associate the image style and its configuration to the figure tag too.

Two other aspect I’ll discuss for each option are:

  • defining css rules
  • CKEditor integration. The aspect to consider is how to resolve the image style and the configuration of an image when editing it. Those information are used to adapt the UI. For instance, some fields are not editable when a given style is applied on the image. For this reason, it’s important to be able to accurately resolve the style of an image.

Option 1
Encoding the image style and its configuration into the classes of the image.

  • a class for the image id (configurable from the image style administration)
  • a class for the border: image-style-border
  • a set of classes for the alignment (image-style-alignment-start, image-style-alignment-center, image-style-alignment-right)
  • a class for the text wrap: image-style-textWrap

Some examples:

  • Image with a style [[image:img.png||class="thestyleclass"]]
  • Image without a style but with a border [[image:img.png||class="xwikiimage-style-border"]]
  • Image with a style and a text wrap [[image:img.png||class="thestyleclass image-style-textWrap"]]

Regarding the adaption for image with captions, in this option we would simply copy all the classes from the image definition into the figure tag.
For instance [[txt caption>>image:img.png||class="thestyleclass image-style-textWrap"]] would be rendered as:

<figure class="thestyleclass image-style-textWrap">
  <img src="..." class="thestyleclass image-style-textWrap" />
  <caption>txt caption</caption>
</figure>

Example of css rules:

/* All images with a border have this style, regardless of their style. */
img.image-style-border {
  border: 1px solid #f00;
}

/* Specific border style for the 'thestyleclass' image style.  */
img.image-style-border.thestyleclass {
  border: 2px solid #0f0;
}

Regarding the integration with CKEditor. The main point is how to resolve the image style and the configuration when editing an images.
Identifying the border, alignment and text wrap is straightforward as we defined a set of css classes for them.
Identifying the style is done by finding the style that has a class that matches one of the class of the image. In case of ambiguity, the first class matching a style would be used. The rest of the classes of the image would simply be preserved on save.

Option 2
Encoding the images style and its configuration into data-* attributes.

  • for the image id data-xwiki-image-style='styleid'
  • for the border: data-xwiki-image-style-border='true'
  • for the alignment (data-xwiki-image-style-alignment='start|center|end')
  • for the text wrap: data-xwiki-image-style-text-wrap='true'

Some examples:

  • Image with a style [[image:img.png||data-xwiki-image-style='thestyleclass']]
  • Image without a style but with a border [[image:img.png||data-xwiki-image-style-border='true']]
  • Image with a style and a text wrap [[image:img.png||data-xwiki-image-style='thestyleclass' data-xwiki-image-style-text-wrap='true']]

Regarding the adaption for image with captions, in this option things are slightly more complicated and different options has been discussed:

  • selectively copying some known attributes to the figure (data-xwiki-image-style* for instance)
  • defining a figure specific prefix, and every attribute starting with this prefix would be applied on the figure instead of the image. We have discussed two prefixes: figure- and caption-. The first one is very technical and we currently only expose the notion of caption through the image “text link” so users might not understand the meaning of the prefix. On the other hand, the caption- prefix could be too specific, for instance if we ever want to also apply attribute to the caption tag itself in the future.

As an example [[txt caption>>image:img.png||data-xwiki-image-style='styleid' figure-data-xwiki-image-style='figurestyleid'] would be rendered as (assuming we use the figure- prefix):

<figure data-xwiki-image-style='figurestyleid'>
  <img src="..." data-xwiki-image-style='styleid' />
  <caption>txt caption</caption>
</figure>

Example of css rules:

/* All images with a border have this style, regardless of their style. */
img[data-xwiki-image-style-border] {
  border: 1px solid #f00;
}

/* Specific border style for the 'thestyleclass' image style.  */
img[data-xwiki-image-style-border][data-xwiki-image-style='styleid'] {
  border: 2px solid #0f0;
}

In this case, CKEditor integration is straightforward since we know exactly which properties to read, without ambiguity.

My vote
+1 for Option 1 and +1 for Option 2. While option 1 could be easier to evolve to support figures, and allows for shorter css selection rules, I tend to prefer option 2 since it does not present ambiguities when resolving the image style configuration of an image.

This vote will end on Tuesday, April 12

Thanks

Thanks

This means we cannot mix multiple image styles? Was this a requirement? Why?

I’m fine with both options. What I don’t like is this:

The user shouldn’t have to modify the image syntax parameters when adding or removing the image caption (e.g. add or remove the figure- prefix). The user should simply specify the image style and the image style should have the proper CSS rules for when the image uses a figure or not. Of course, the rendering should (selectively) copy the necessary image syntax parameters to the figure block.

So +1 for option 1 and +1 for option 2 provided we don’t use any prefix.

Thanks,
Marius

I don’t think it would make sense to have several style for a single image. For instance, a style also define what the end user can configure. What would it mean to have two styles for a single image, where one allow to set a border while the other one forbid it?

I don’t see why we should have exactly these attributes. Why is it possible to enable/disable the border but not, e.g., the background color or rounded corners or drop shadows (just to name a few examples)? Setting exactly these properties as an API is bad idea in my opinion. Why can’t the style define which properties exist (in the form data-xwiki-image-style-* in the case of the second option)? Could we maybe agree that everything in the form data-xwiki-image-style-* can be used and which properties exist is an implementation detail of the corresponding styles?

Apart from that I’m slightly against option 1 if we don’t use any prefix as it removes the possibility for advanced users to set a class only on the figure or only on the image, which is currently possible. On the other hand, if we only copy some style attributes in case of option 2 I think the probably that we break any existing use case is minimal. So -0 for option 1 and +1 for option 2.

+1

According to our best practices, anything starting by data-xwiki-image-style is reserved to the Image Style module from XS. I was mostly listing what is going to be use in practice.

Let the CSS decide who wins, and let the user decide if mixing the styles produces good / useful results of not. Your argument is that there are cases when the styles are in conflict, but that doesn’t mean all the styles are in conflict. If two styles can be used at the same time, then why should we prevent the user from doing so?

I don’t understand. The fact that the CSS class from the image is copied to the figure doesn’t mean it overwrites it. It should simply be added to the existing list of CSS classes.

(% class="foo" %)
[[caption>>image:some.png||class="bar"]]

should produce:

<figure class="foo image bar">
  <img src="..." class="bar"/>
  <figcaption>
    <p>caption</p>
  </figcaption>
</figure>

The only difference from now is that the class specified the image is added to the figure when a caption is used. I don’t see what’s wrong with that.

As I’ve said, it is no longer possible to set a class that is just set on the image element but not on the figure element. Further, the conversion back from HTML is difficult, we would need to check which classes are only on the figure and not on the image to get the list of classes to put on the figure, and this could still modify the list of classes the user initially set on the paragraph/figure (if the user explicitly set the class on both, it will only be on the image afterwards).

Thank you all for the votes.

Final results:

  • Option 1: +2
  • Option 2: +3

I don’t think this is a good thing for two reasons:

  1. It makes the UI more complex to use and understand
  2. Advanced users can always do what they want manually