Updated: Comment #0
Problem/Motivation
In #2014895: Image captions & alignment (for inline images), we introduced aligning and captioning of images in Drupal 8 — at long last Drupal will finally ship with that!
Currently, I'm collaborating with the CKEditor developers on getting Drupal to use CKEditor 4.3, including its leap forward in image handling (which will allow us to get rid of a whole bunch of custom code). That's what's blocking #2039163: Update CKEditor library to 4.4: some upstream changes.
We — or rather, they, because they're doing all the hard work! — are very close to a patch that will solve that issue. However, in doing so, they encountered a fundamental flaw in the code that was introduced in #2014895.
The problem is this:
filter_caption
always transforms<img>
s into<figure><img><figcaption</figure>
, as long as the image has either adata-caption
or adata-align
attribute.- In other words: even an aligned image will get wrapped in a
figure
tag, even if no caption is set. This is beneficial for the designer/themer: the same CSS handles both captioned and aligned images. If desired, (s)he can special case the "there's no caption" case, but out of the box, but that's optional. Simple. - But what about images aligned in the middle of text?
- The above wraps all images that have either a caption or an alignment in a
<figure>
tag. Which means we turn them into block-level elements… even if they're in fact an inline image and not a block image! This results in invalid HTML, and may break styling too. - That's what we failed to see/address/support. However infrequent on most sites, there are valid use cases for aligning images. Not to mention that this is how image alignment is demonstrated/explained in many if not most tutorials.
In other words: CKEditor 4.3's image2
plugin does things correctly, filter_caption
does things incorrectly, resulting both in a mismatch between what the user sees in CKEditor and what the end result looks like, as well as invalid HTML with the corresponding consequences.
Proposed resolution
The solution is simple:
- stop
filter_caption
from transforming images that only have thedata-align
attribute into<figure><img></figure>
- add CSS to handle left/center/right aligned images, which we can do very elegantly since we dropped IE8 support:
img[data-align="(left|center|right)" { … }
Remaining tasks
None.
User interface changes
None, other than that the output of <img src="cat.jpg" data-align="right" />
will now look differently. In the third example in this screenshot, you would now see just the llama, not the gray background + border.
API changes
None.
Comment | File | Size | Author |
---|---|---|---|
#6 | pero-con-caption-2.png | 117.85 KB | jessebeach |
#6 | dog-no-caption-2.png | 114.23 KB | jessebeach |
#6 | text-align-2.png | 110.26 KB | jessebeach |
#4 | interdiff.txt | 11.39 KB | Wim Leers |
#4 | filter_align_fix-2170085-4.patch | 10.4 KB | Wim Leers |
Comments
Comment #1
Wim LeersComment #2
jessebeach CreditAttribution: jessebeach commentedI'd prefer to use classes for alignment rather than attributes. Functionally they're the same (other than selector weight), but in terms of DX, themers are going to recognize a class over an attr-based selector more readily and especially for these types of themer/content editor facing elements we should stick with easier patterns.
Wim, do we expect the image in the editor to be wrapped in a
figure
tag even when the caption option is disabled?The image started off un-captioned; I didn't just uncheck the box in the image above. All images are rendered as being "captioned" in the WYSIWYG. Is that just to get the affordance of the caption-wrapping visual chrome?
Comment #4
Wim LeersGreat review, thanks Jesse!
Ugh, excellent point: I updated the PHP code, but not our current, custom CKEditor plugin that mimicks the current PHP's behavior.
It's going to be fixed soon, in #2039163: Update CKEditor library to 4.4, when we get to throw away our custom
drupalimagecaption
plugin and use CKEditor's officialimage2
plugin instead. I've updated the code to deal with the new reality for now.I removed these. "left" must mean "left", always.
Many epic calls have been had about this issue. It's a trap. If you want to know why, see #1907418: Make CKEditor's alignment + underline buttons available (but not enabled by default) to understand why RTL-dependent alignment is problematic.
These class names are already taken for the generic text alignment classes, see
system.module.css
and #1907418. However… considering that those are for text alignment and the class being used here must work to align HTML elements of any kind, I think these names are fine.I kept these, and updated the tests.
This always sets the alignment class on the image, but doesn't remove it if the image is captioned, which then causes both the caption and the captioned image to be floated. That's bad.
The other changes also break the "no valid alignment" case, so the assertions testing that will fail.
Comment #5
jessebeach CreditAttribution: jessebeach commentedI see what you did there with the
text-align
classes. Clever stuff:Comment #6
jessebeach CreditAttribution: jessebeach commentedGreat changes. Love this patch. Here are a couple screenshots from my testing.
An image without a caption. The "figure" chrome is no longer rendered.
An image with a caption. The "figure" chrome is rendered.
Centered text
I like the move of the 'align-*' classes to the system css as well. These really are general-use classes. WordPress has almost the same set, if not exactly the same selector names.
Comment #7
webchickCommitted and pushed to 8.x. Thanks!
Comment #8
Wim Leers