Problem/Motivation

CKEditor 4 requires setting alt text for all images when they are being inserted using the CKEditor Drupal image plugin. In CKEditor 5 the user needs to remember to insert the alt text manually since the process of adding images never even displays the form where alt text can be inserted. Since the process in CKEditor 5 could end up having images accidentally not having alt texts, it could be considered as an accessibility regression.

Proposed solution

  1. Open image alt text form on the contextual balloon after uploading image
    1. If multiple images have been uploaded, form is opened for the last uploaded image
  2. If alt text is not added for the image, a warning message with text "Add missing alternative text"
  3. The message is a button. Clicking the button opens the alt text form for that image.
  4. While the alt text form is visible, the warning message of the selected image is hidden

Remaining steps

  1. Review the UX
  2. There isn't screenreader interface for this at the moment. We need to decide if we need one.
  3. Code needs some cleanup, some of the code is not yet commented.
  4. Need additional test coverage to:
    1. Ensure that alt text form is opened after image upload
    2. Ensure that alt text form is opened by clicking the button in the warning message
    3. Ensure that warning message is not visible on selected image when the alt text form is open
  5. We probably should move the SVGs from data backgrounds to files
  6. Some tweaks for responsive styles and for small images
  7. Ensure that the toolbar positioning is updated when the decorative image toggle state changes
CommentFileSizeAuthor
#93 3222757-84-d93-reroll.patch71.33 KBlauriii
#92 3222757-84-d93.patch71.46 KBlauriii
#84 3222757-84-d94.patch71.37 KBlauriii
#84 3222757-84-d10.patch71.17 KBlauriii
#74 Screen Recording 2022-03-25 at 10.44.27.gif556.17 KBlauriii
#73 multi upload responsive indicator.mov9.3 MBWim Leers
#59 drupal-media-no-decorative-option.png156.01 KBnod_
#59 image-toolbar-offset-decorative-after-after.png61.13 KBnod_
#59 image-toolbar-offset-decorative-after.png61.48 KBnod_
#59 image-toolbar-offset-decorative-before.png61.56 KBnod_
#59 image-warning-hidden.png27.4 KBnod_
#59 image-warning-overflow.png22.2 KBnod_
#54 Screen Shot 2022-03-02 at 14.44.58.png594.57 KBlauriii
#53 Screenshot 2022-02-28 at 19.20.12.png13.74 KBWim Leers
#53 upload success on top of alt warning.mov5.19 MBWim Leers
#52 Screen Shot 2022-02-28 at 12.23.30.png643.57 KBlauriii
#51 Screen Shot 2022-02-24 at 12.54.33 PM.png285.87 KBbnjmnm
#41 cke4-a11y-checker-img-alt.mov5.13 MBWim Leers
#41 cke4-a11y-checker-img-alt-2.png226.13 KBWim Leers
#41 cke4-a11y-checker-img-alt-1.png255.33 KBWim Leers
#33 6351E50E-5CE3-4162-9B25-8D2BCDA8898A.jpeg675.17 KBlauriii
#19 interdiff_16-19.txt23.53 KBbnjmnm
#19 3222757-19.patch30.03 KBbnjmnm
#16 interdiff_14-16.txt25.49 KBbnjmnm
#16 3222757-16.patch26.65 KBbnjmnm
#14 3222757-14.patch23.18 KBbnjmnm
#14 Screen Recording 2022-01-04 at 3.45.29 PM.mov17.63 MBbnjmnm
#6 Screen Shot 2021-08-05 at 7.38.41 AM.png1.48 MBbnjmnm

Issue fork drupal-3222757

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Issue fork ckeditor5-3222757

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lauriii created an issue. See original summary.

lauriii’s picture

Title: Make alt text required » Make image alt text required
Wim Leers’s picture

Issue tags: +Accessibility, +stable blocker

Thanks for filing this issue — this is one of the first things I voiced as a concern about CKE5 actually 😅😬

bnjmnm made their first commit to this issue’s fork.

Wim Leers’s picture

👀🥳

bnjmnm’s picture

A visual warning is now able to appear (I regret to say this is probably not the final design, however).

Next step is to see how to best enforce this. Presumably serverside validation, but maybe CKEditor5 has some cool options I'm not yet familiar with?

Wim Leers’s picture

Nice progress here!

(Nice choices of testing images btw 😆)

Presumably serverside validation, but maybe CKEditor5 has some cool options I'm not yet familiar with?

Let's ask them? 😊

But perhaps let's first discuss what we expect from client-side validation: does that mean that CKEditor 5 detects the submit event, cancels it, shows a dialog/warning, and only if you then say "ignore", it will proceed?

bnjmnm’s picture

For enforcing the alt text on submit, it looks like it may be possible to leverage CKEditor 5's existing submit listeners, the implementation of which can be found here https://github.com/ckeditor/ckeditor5/blob/550b168/packages/ckeditor5-co...

Potentially, this could be as simple as adding a listener that calls preventDefault() if there are img tags without alt.

rachel_norfolk’s picture

Is it possible someone would be adding a "decorative" image via creditor? If so, they should be able to add an empty alt text, shouldn't they?

Something along the lines of Rule 5 in https://abilitynet.org.uk/news-blogs/five-golden-rules-compliant-alt-text

rachel_norfolk’s picture

Sounds good!

Wim Leers’s picture

Title: Make image alt text required » [drupalImage] Make image alt text required
Project: CKEditor 5 » Drupal core
Version: 1.0.x-dev » 9.3.x-dev
Component: Code » ckeditor5.module
Category: Feature request » Task
Priority: Normal » Major
Issue tags: +Needs tests

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bnjmnm’s picture

Status: Active » Needs review
FileSize
17.63 MB
23.18 KB

Here's a patch as I'm having difficulty creating an MR against core due to this issue beginning as one for the contrib module.

This introduces submission prevention. The approach suggested by the CKEditor 5 team wasn't working as the form still redirects on submit. This instead targets the submit button itself, and prevents submission if alt text is missing.

The visual experience here is intentionally lacking. I'd like to get some eyes on this before devoting time to styling, etc. See the attached video for the no-frills, but completely functional, experience.

Still needs tests, but setting to NR so DrupalCI runs (and reviews would still be good...)

Status: Needs review » Needs work

The last submitted patch, 14: 3222757-14.patch, failed testing. View results

bnjmnm’s picture

Fixed failing tests, added new tests for the functionality introduced here.

bnjmnm’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 16: 3222757-16.patch, failed testing. View results

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
30.03 KB
23.53 KB

The remaining failing tests were because they included saving an image without alt text, so that's further evidence this is doing its job.

Wim Leers’s picture

Status: Needs review » Needs work
Related issues:

It works — just like in #6 — but my test imagery isn't quite as epic as @bnjmnm's 😅😂

  1. +++ b/core/modules/ckeditor5/css/image.css
    @@ -0,0 +1,23 @@
    +  right: 20px;
    

    🤓 Needs LTR support.

  2. +++ b/core/modules/ckeditor5/css/image.css
    @@ -0,0 +1,23 @@
    +  content: "☠️";
    

    😆

  3. +++ b/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js
    @@ -449,6 +449,7 @@ export default class DrupalImageEditing extends Plugin {
    +          'class',
    

    🤔 Why do we need to allow class?

    This is the first model attribute we allow that does not end up in the downcast.

    Shouldn't we instead add alt here and make the use of a class an implementation detail of the upcast?

  4. +++ b/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js
    @@ -517,5 +519,73 @@ export default class DrupalImageEditing extends Plugin {
    +        const hasAlt =
    +          data.item.getAttribute('alt') &&
    +          data.item.getAttribute('alt').length > 0;
    

    This needs to be refined to match the pattern introduced in #2307647: [Follow-up] Allow manual override of required image alt text in the Text Editor image dialog when appropriate after lengthy discussions with accessibility maintainers — we have no choice but to match that exactly to ensure backwards compatibility is guaranteed.

        // The alt attribute is *required*, but we allow users to opt-in to empty
        // alt attributes for the very rare edge cases where that is valid by
        // specifying two double quotes as the alternative text in the dialog.
        // However, that *is* stored as an empty alt attribute, so if we're editing
        // an existing image (which means the src attribute is set) and its alt
        // attribute is empty, then we show that as two double quotes in the dialog.
        // @see https://www.drupal.org/node/2307647
        $alt = $image_element['alt'] ?? '';
        if ($alt === '' && !empty($image_element['src'])) {
          $alt = '""';
        }
        $form['attributes']['alt'] = [
          '#title' => $this->t('Alternative text'),
          '#description' => $this->t('Short description of the image used by screen readers and displayed when the image is not loaded. This is important for accessibility.'),
          '#type' => 'textfield',
          '#required' => TRUE,
          '#required_error' => $this->t('Alternative text is required.<br />(Only in rare cases should this be left empty. To create empty alternative text, enter <code>""

    — two double quotes without any content).'),
    '#default_value' => $alt,
    '#maxlength' => 2048,
    ];

lauriii’s picture

Issue summary: View changes

Validating contents of the text editor is a new pattern for Drupal and I'm not sure there are many other systems doing it. I'm concerned that it will be difficult for users to understand where the error is occurring, and how it can be fixed.

The currently used pattern where image alt text is validated when image is being inserted or edited seems potentially better for UX since the image cannot be inserted without adding an alt text. For me, that is close to the ideal UX since it leads the user naturally to a point where they have to enter the alt text. I think we should explore if opening a new dialog before inserting the image or by opening the existing alt text form in the inline toolbar we could achieve similar UX without actually having to validate the contents of the text editor.

This issue is also impacted by the fact that in future we'd likely want to integrate the media library to the image upload functionality which potentially moves the image upload back to a dialog to match the current media library UX.

I also noticed that the current validation error for not having alt texts in CKEditor 4 is a bit confusing since it doesn't explain when alt text is needed and when it's not. That's also not ideal for accessibility since bad alt texts, as well as unnecessary alt texts can degrade the experience too. This is the current message:

Alternative text is required. (Only in rare cases should this be left empty. To create empty alternative text, enter "" — two double quotes without any content).

I think we should link to some resource like https://www.w3.org/WAI/tutorials/images/decision-tree/ that helps users to determine whether the image should have a link or not.

Wim Leers’s picture

I think we should explore if opening a new dialog before inserting the image or by opening the existing alt text form in the inline toolbar we could achieve similar UX without actually having to validate the contents of the text editor.

That still comes with a huge cost: users won't be able to upload multiple images anymore, like they can today in CKEditor 5.

This issue is also impacted by the fact that in future we'd likely want to integrate the media library to the image upload functionality which potentially moves the image upload back to a dialog to match the current media library UX.

Then I think we'd be better served by always treating all new image uploads as media uploads. Issue for that: #3073901: Determine an upgrade path from CKEditor image button to media library.

But even then … we won't be able to assume that Media/Media Library are installed on all sites… 😬

I also noticed that the current validation error for not having alt texts in CKEditor 4 is a bit confusing since it doesn't explain when alt text is needed and when it's not. That's also not ideal for accessibility since bad alt texts, as well as unnecessary alt texts can degrade the experience too. This is the current message:

I think we should link to some resource like https://www.w3.org/WAI/tutorials/images/decision-tree/ that helps users to determine whether the image should have a link or not.

I understand that there actually is even more nuance. But how do you want to present that decision tree without making the UX (very) complicated? What we have there right now is the result of much discussion. See the 3 core issues I linked in #10.

bnjmnm’s picture

This needs to be refined to match the pattern introduced in #2307647: [Follow-up] Allow manual override of required image alt text in the Text Editor image dialog when appropriate after lengthy discussions with accessibility maintainers — we have no choice but to match that exactly to ensure backwards compatibility is guaranteed.

It's not clear to me if it's currently possible to provide an alt tag with an empty value (alt=""). I left a comment on a CKEditor 5 issue dealing with empty attribute values, which as of earlier today is officially on the CK team's radar as I noticed it was tagged with "squad:core".

Wim Leers’s picture

Yep, @lauriii raised that during yesterday's CKEditor 5 meeting 😊👍

lauriii’s picture

Discussed the approach in the UX meeting today #3257468: Drupal Usability Meeting 2022-01-14.

Some concerns were raised on the call that it needs to be clear when the image is being uploaded that the alt text is required. The most natural way to do that is to show the form for entering alt text (although an alternative approach was proposed where it would be indicated by showing a status message). Since multiple images could be uploaded at once, this will likely need something on top of the existing CKEditor contextual toolbar.

The approach that the group on the UX meeting recommended was approach where image upload would open a dialog, similar to what happens on media upload. On the dialog, user would be asked to enter alt texts for all uploaded images before proceeding. This would all happen after the images have been selected for uploading, so the experience of dragging images to CKEditor, or pressing the image upload button would remain the same.

lauriii’s picture

#24 It seems like @Reinmar from the CKEditor team is unable to reproduce the problem. I also tested the examples from the Github issue in our environment and I could get the correct behavior with writer.setAttribute('alt', '', viewElement);. I wonder if there's something in your environment that is causing the bug?

lauriii’s picture

I was looking for other CMSs to see how they handle this. Based on a quick analysis, I failed to find any other CMS that would require alt text for images on upload. Some CMSs use the filename as the alt text by default, some simply leave the alt text empty. That made me challenge the current approach where we set alt text as required on image upload.

  1. Gaps in the current approach:
  2. Image alt text could be missing for an existing image which was uploaded using a different text editor, through an API, using a source editor etc, resulting in the content author never becoming aware of that unless they edit the image and open the image dialog.
  3. Remote images could be inserted to CKEditor by copy and pasting content. This would also never go through the image upload form, meaning that there isn’t any mechanism prompting the content author to enter alt text.
  4. The current process only supports uploading a single image at a time.

Proposed new approach

  1. Instead of considering this as validation, consider it as helpful guidance for users. This means that we won’t validate the form on form submission for missing alt text. It also means that we shouldn’t use red for communicating missing alt texts to users (which is usually associated with errors). Instead we would use more toned down gray to provide helpful indication that an alt text is missing from an image.
  2. When images are being uploaded the contextual toolbar tray is opened for the first image to remind the content author about adding alt text to images. When an image that doesn't have an alt text set is being clicked, the alt text form is opened automatically instead of the regular contextual menu.
  3. We might have to use additional data-attribute for storing information on whether image alt text was intentionally left out so that we can recognize the instances where the alt text was never entered.

I believe this approach is worth trying because it provides similar UX to what CKEditor 5 provides out-of-the-box, and it is orders of magnitude simpler to implement when compared to the dialog approach that was suggested by the UX meeting (in particular because large parts of this have been already implemented).

bnjmnm’s picture

I'm not opposed to shifting from full-enforcement to strong-and-visible-encouragement. It's still more assertive than similar products, but not as disruptive as the current mandatory enforcement. I suspect this can result in a similar level of good alt text practices - perhaps even better because

  • it doesn't lead to circumstances where someone enters a gibberish alt text string to get out of the form (lets assume not everyone reads the help text).
  • It doesn't create pressure to add alt text to an image that is arguably decorative
  • The alt text can be updated when it works best in an individual's workflow. Particulalry when multiple images are uploaded, being expected to provide alt text for them all may take the user out of the task flow that would have ultimately led to better written alt text

I think this would first need a11y maintainer signoff, ideally more than one of us looking at it. That signoff should solely be if the switch from enforcement to encouragement is acceptable. The fact that this would be a UI change from CKEditor 4 can be vetted by product & UX - but there's no point in presenting this to them until there's A11y approval.

bnjmnm’s picture

Title: [drupalImage] Make image alt text required » [drupalImage] Make image alt text required or strongly encouraged
Luke.Leber’s picture

My $.02 - https://www.drupal.org/project/decorative_image_widget seems to have hit the nail on the head here. I'd support a similar explicit approach.

This seems to imply that there would not be any complication of server-side validation, because for all intents and purposes, the field isn't "required" -- it just takes an extra step for users to turn the requiredness off by confirming the image is decorative.

andrewmacpherson’s picture

I don't know what "contextual toolbar tray" refers to. What is it?

Re. #28:

Some CMSs use the filename as the alt text by default

We MUST NOT do this, whatever other outcome we reach. It's a stupid and dangerous idea.

Prepopulated text alternatives will just end up getting saved.

Filenames are typically gibberish, and worse than images with missing text alternatives. And it would be our fault for prepopulating it :-(

lauriii’s picture

I think I wasn’t clear about why I mentioned the filename as default alt text in my comment. It was supposed to be an example of how much behind some our competitors are when they are doing that. I’m definitely not recommending we would do that, so I think we are on the same page with that.

The contextual toolbar tray is a CKEditor specific toolbar tray, which is displayed in a balloon. It’s similar to Quickedit but it’s only displayed when there are contextual menu items available for the focused CKE element. Here’s a picture of how it looks like:

itmaybejj’s picture

Another vote for the Decorative Image Approach -- an affirmative decision is required (description or affirmation that the image has no contextual meaning). Affirmative decisions in my opinion are more likely to encourage editors to read the help text, which should explain that the alt text should describe the image's "meaning in context" rather than simply describing what objects it contains.

I would also recommend a live inline validation helper that flags possibly suspicious words ("image", "photo" etc) and almost certainly suspicious strings ("http," ".jpg" etc). I have JS to test for this already written in Editoria11y; it could be pulled out and run, debounced against typing, with a tooltip thrown or the field description updated when suspicious text is found. Light-touch nudges like that have done a ton to passively educate users in our systems.

mgifford’s picture

Here's a good example of what to do - https://accessibilitycluster.com/main-results/text-alternative-feature-%...

Lots of examples out there about what not to do.

mgifford’s picture

We can restrict alt text with .jpg or .png in them pretty easily.

mgifford’s picture

Oh yes, I'd also like to say that in Drupal 8 we made it required, but you could over-write that. I would see making the image alt text strongly encouraged as a regression, but that might depend on the on the implementation.

It should take some effort to not add alt text. It might still be easier to over-write that, as we do in Drupal 8, but it should be relatively easier to fill in alt text, compared to not adding any alt text at all.

lauriii’s picture

Oh yes, I'd also like to say that in Drupal 8 we made it required, but you could over-write that. I would see making the image alt text strongly encouraged as a regression, but that might depend on the on the implementation.

I agree that if we look only image uploads, it could be seen as a regression. Do you think that overall it’s still a regression when we take into account how the proposed approach could encourage adding alt text to existing images, as well as images that are added outside of the image upload (by copy pasting content or through an API)? Also, how big of an regression do you think it is, if it’s weighed against the cost in lost UX?

bnjmnm’s picture

Asked @mgifford via Slack about @lauriii's question in #38

Response 1:

I think there might be a few possible regressions with CKEditor 5. Tables are another area of concern.

(While tables are not in scope of the specific issue, I wanted to preserve Mike's response completely - he provides useful feedback! )

Response 2:

This is the direction that we should be going if we can’t retain the functionality of CKEditor 4 [An accessibility tool with the name] Main results

To supplement, this is the alt-text specific portion of the direction recommended by @mgifford

bnjmnm’s picture

It looks like the alt text approach in Main Results suggested by Mgifford is implemented with the assumption that all images are added via a dedicated button in the editor - the same assumption CKEditor 4's alt text enforcement does. Assuming I'm understanding it correctly, the Main Results approach would still be unaware of images add via copy/paste, source editing, or API.

What @lauriii is suggesting would be aware of an images's alt-text status, regardless of how it was added, an improvement that I think is an acceptable tradeoff for no longer having the immediate & mandatory dialog requesting alt text. There would still be plenty of UI/AT feedback to alert the user about the lack of alt text, but it wouldn't be constrained in a modal anymore.

One thing I did like about the Main Results approach, and would like to implement here regardless of the broader approach is a checkmark for "decorative" instead of requiring the user to type empty quotes.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
255.33 KB
226.13 KB
5.13 MB

Urgency

It's mid-February now.

We've been gathering feedback from UX and a11y teams for a month now (see #25).

We really need to get this moving ASAP if we want to get CKEditor 5 stable in time for Drupal 9.4.

I'm going to try tie the entire discussion together, because I believe consensus is actually already achieved, without us realizing? 🤓😄

Proposal: addition to @lauriii's #28

If we do exactly what @lauriii proposed in #28's Proposed new approach, but with an added 4th step, which would be:

  1. Upon saving, we check that for each <img> tag present in the text editor, an explicit choice was made: either it was marked as decorative or alternative text is provided. If that is not the case, we force the content author at the time of saving that they need to decide that.

@lauriii mentioned in #22 he was concerned about the UX for this step. Good news: this is not entirely new territory. See https://ckeditor.com/ckeditor-4/accessibility-checker/demo/ (click the button in the top left). You'll see this:

First image with problematic alt surfaced by CKEditor 4's Accessibility Checker.
Second image with problematic alt surfaced by CKEditor 4's Accessibility Checker.

I've also attached a screencast to show it in action.

Addressing feedback from a11y maintainers and experts

@andrewmacpherson's feedback in #32 was already fully addressed.

@itmaybejj (maintainer of https://www.drupal.org/project/editoria11y, see https://accessibility.princeton.edu/news/introducing-editoria11y for an intro and, https://itmaybejj.github.io/editoria11y/demo/ for a live demo!) appears to be generally on board and is advocating for nudging and educating. That is essentially what the proposal here does too.

@mgifford raised concerns. I think @bnjmnm already answered them. Let me spell it out a bit more:

There would still be plenty of UI/AT feedback to alert the user about the lack of alt text, but it wouldn't be constrained in a modal anymore.

This I think is the crucial bit. I am confident it will adequately address @mgifford's concerns. To be more specific:

  • I would see making the image alt text strongly encouraged as a regression, but that might depend on the on the implementation.
    → the expanded proposal would still make it required, just not immediately upon uploading. You still won't be able to save the text without explicitly specifying <img alt>!
  • It should take some effort to not add alt text.
    → See above.
  • It might still be easier to over-write that, as we do in Drupal 8, but it should be relatively easier to fill in alt text, compared to not adding any alt text at all.
    → That would still be the case.

Why not do exactly what we did in CKE4?

I'd like to emphasize one more thing that @bnjmnm wrote:

acceptable tradeoff for no longer having the immediate & mandatory dialog requesting alt text.

It is that immediate and mandatory UX that we had in CKEditor 4 (well, in EditorImageDialog) that if we brought it to CKE5 too would be:

  1. a huge UX regression compared to CKE5's default image uploading/editing experience — with likely disastrously bad alternative text like @bnjmnm explained in #29
  2. a significantly inferior UX in Drupal compared to other CMSes

In CKE5, one can drag and drop multiple images at once into the editor. This is commonly needed and highly valuable. Popping up multiple mandatory modals completely interrupts the content creator's editing flow. (Again like @bnjmnm explained in #29.)

And like @lauriii and @bnjmnm explained, already in CKE4/Drupal 8|9, copy/pasted content won't get guaranteed <img alt> anyway. The reality today is that many people do create content first in Google Docs/Word and then copy/paste it into the CMS. It's important that we nudge creators of such content to also specify <img alt>. Ignoring that common scenario does more harm.

That's why we're spending so much time on finding a different approach. We basically want to do what @itmaybejj is suggesting too: light-touch nudges (see #28's point 1.), but switch to forceful messaging/requiredness upon saving (this is what my addition to @lauriii's #28 covers).

tl;dr: only nudges/indicators while creating content to avoid disruption, use force when saving.

lauriii’s picture

That still doesn't address the concern that I raised in #22 about validating contents of text editor being a new pattern (and this concern was shared with folks on the UX call mentioned in #26). The part that I've been particularly concerned about has been that preventing form submission in case violations are detected inside the text editor will result in complicated/reduced UX.

The accessibility checker plugin doesn't prevent form submission, and therefore it doesn't resolve that problem for us. The approach that I proposed in #28 would take our alt text approach to almost exactly where the accessibility audit plugin is, with the exception that we would check for missing alt texts automatically without having to trigger the accessibility audit manually.

Wim Leers’s picture

The part that I've been particularly concerned about has been that preventing form submission in case violations are detected inside the text editor will result in complicated/reduced UX.

But … if we have to choose between the old pattern and the new pattern:

  1. The UX that CKE4/EditorImageDialog offer today: one image at a time, forced disruption of content creation, not checking for pasted images' alt
  2. The UX that I proposed, which indeed has in-editor validation.

… then isn't the new pattern clearly superior?

I did not propose the use the exact CKE4 accessibility checker implementation, but to show what the UX could look like for providing validation errors inside the text editor. I.e. I intended it as inspiration, not as implementation spec.


Another thought: if we were to add validation in CKEditor 4 for pasted images without alt, we would have to implement something similar to this too, wouldn't we?

If we generalize that idea, it is essentially validation constraints for data in a field. If we had infrastructure like that, we would also be able to provide validation errors for broken media embeds (invalid media UUID for example), links to pages in Drupal that no longer exist, and so on.

My point being: this is not a new problem. It's a problem we've always had. With CKEditor 4, we just implemented the simplest possible thing, while disregarding many of the UX implications. The solution we pick could work in multiple text editors.

lauriii’s picture

I'm not thinking that introducing the pattern of validating text editor content and preventing form submission would lead to superior UX to what we have now - otherwise I obviously wouldn't push back on that. Validating form elements is a pre-existing pattern which has well defined UX and accessibility patterns unlike validating editor content.

I did not propose the use the exact CKE4 accessibility checker implementation, but to show what the UX could look like for providing validation errors inside the text editor. I.e. I intended it as inspiration, not as implementation spec.

I understand that. What I was trying to say is that I think the accessibility checker implementation is superior over the proposed approach here, since it doesn't prevent saving editor content with accessibility violations.

If we generalize that idea, it is essentially validation constraints for data in a field. If we had infrastructure like that, we would also be able to provide validation errors for broken media embeds (invalid media UUID for example), links to pages in Drupal that no longer exist, and so on.

I'm -1 for adding form validation for these things too - I don't think preventing form submission due to any of these reasons would lead into superior UX. However, what would be helpful is to provide guidance within the editor about missing media and broken links, similar to what I'm proposing we should do with the image alt text.

nod_’s picture

After reading the various points I'm with lauriii and ben in that we shouldn't prevent form submission when there are issues. For me it's the best tradeoff of result/effort.

I don't see this a matter of choosing between EditorImageDialog and in editor validation. This is still experimental so anything would be better than what we have today. We can start with strong warnings inside the editor, see how it goes and upgrade to form submission prevention later if people are on board with it (and new people are ready to actually contribute to it, so it's not always down to the same folks).

Overall I think we agree that we don't want the EditorImageDialog UX. Doing the in-editor warning needs to happen whether we prevent form submission or not so let's ship that one first and see if it's worth it to do the second step of form submission prevention once the in-editor warning is live. This also raise the question on how to evaluate the use of this feature, how can we measure the improvement we expect to see with this feature? I see lots of hope this will make things better but not many measurable things to check for before/after this gets in. And if we have no way or plan on how to measure the impact I personally don't feel like spending a lot of effort on it compared to all the other subjects we have to look into.

/kinda off topic
So I guess this is a question for the accessibility team. We know how to measure the accessibility of core themes and know if they're accessible or not and we have a core gate around this. What about user content? how is the accessibility of this evaluated/measured given all that can go wrong with a Drupal site implementation? Is Drupal's responsibility only to provide tools to enable users to write accessible content or do we provide tools that constrain users to write accessible content, where is the line? In both cases what type of things can we look for/measure to see if the decision we made has a positive (or negative) impact? from word of mouth, periodic study, etc.
/kinda off topic

If we really want to show a big red error, displaying it at render time to users who have edit permission would be more in line with what we're used to do, since a text filter could somehow automatically fix this.

itmaybejj’s picture

From a "can of worms" perspective, I'm uncomfortable preventing submission/save of the node; that seems fraught with potential downstream issues.

I think my preference would be, in order:

  1. On pasting in an inline image (or a bunch of them), immediately open a modal wizard where you step through each image and either add the alt or affirm it is decorative (an immediate workflow).
  2. Or: newly pasted images are created in a limbo state -- e.g., in the CKEditor editor window they render at half-transparency-half-red with an alert icon indicating they need an alt decision before they will display, and they don't appear after save in the render array until this is addressed. But nothing is deleted.

As to nod_'s question about whether we should enable or force accessibility -- it is my opinion that we should take the "enable" approach where laws and guidelines are ambiguous or mixed from region to region, and take the "enforce" approach where we can reasonably assume all or most our users are legally required to do something, and the server can always tell when something is wrong. E.g.: I think we should enforce alt text, because it is a clear violation of enforceable laws in North America and the E.U. and many other countries. But most other things Editoria11y flags I would put in the "enable/nudge" category -- heading order, meaningful links, etc.

lauriii’s picture

Thank you @itmaybejj for your input!

#46.2 is interesting proposal. I'm wondering if that could be additional filter which could be enabled by organizations that want that behavior? That would then allow them to decide whether they want the alt text to belong to a "enforce" or "enable/nudge" category. 🤔

Wim Leers’s picture

(Cross-posted with #46 and #47.)

Discussed this in detail and at length with @lauriii, @nod_, @bnjmnm and @xjm.

We are all strongly convinced that the approach I outlined, but with the change that we will not trigger an error at form submit time is the best way forward. We may need to tweak certain aspects, and we can see various ways of that playing out/adjusting to feedback.

But we're all convinced that this has by far the best chance of both improving UX compared to the terrible UX in CKE4/EditorImageDialog (which by the way I am responsible for — so mea culpa!) while achieving better alt specified on <img> by content authors, for more use cases (not just image upload, but also manual source manipulation and copy/pasting from external sources).

So, because time is definitely starting to run short, we're going to go ahead and start implementing this approach. Even more so because CKEditor 5 is not yet stable, and we need to get it to stable. Right now there is nothing nudging/forcing/… content creators to specify alt. By the end of this issue we'll at minimum have made a huge leap forward.

So: high time we start implementing this, if we want to meet the goal of getting CKEditor 5 stable by 9.4.0.

itmaybejj’s picture

Works for me; Wim et al: thanks for taking point on this.

@lauriii -- would be a great optional filter. Might be something I can take a look at in summer/fall if nobody else has chased it yet; I rather expect CKEditor5 to force me to more tightly integrate certain nudges into workflow to keep them useful anyway. I'm already seeing that in WordPress with the block editor -- my post-save nudges feel like they come too late in the workflow.

solideogloria’s picture

I like the idea of having an optional filter that a site admin can turn on. Making it always "enforce" for all Drupal sites wouldn't be good, though, as there are plenty of times where alt text doesn't make sense, such as tracking pixels, decoration that would mess with screen readers, etc.

bnjmnm’s picture

Status: Needs review » Needs work
FileSize
285.87 KB

Now that a direction is decided, I advanced it a little bit.

The most recent commit removes the submission blocking, as we've decided that isn't needed. The default alt text form has been overridden with our own files and exported as drupalImageTextAlternative Currently, most of the changes in the overridden files are cspell and prettier related, but there's also this toggle switch that currently does nothing, but it (or something similar) will be the means of marking an image as decorative instead of having to enter empty quotes.

lauriii’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
643.57 KB

Adding screenshot of how this looks like:

I think this is ready for initial review.

Wim Leers’s picture

This is a review only for the UX, not the code. Keeping at Needs review for that reason.

Generally, it works great! 👍 But I spotted a few edge cases 🤓

Problems spotted

  1. The "uploaded" checkmark animation is on top of the "missing alt text" warning icon. This makes it very easy to miss the first time around.
  2. The contrast of the "missing alt text" warning icon may not be adequate with some images? For the test image that I happened to choose, it's definitely easy to miss.
  3. On an image that already has alt, editing the existing alt through the UI and clicking the green checkmark to confirm does not have any effect.

For the first two problems, see the attached screencast.

Suggestions for each

  1. The "missing alt text" warning icon should A) be positioned differently, B) probably also be animated? Or maybe better still, we should override that and have the green checkmark transform/animate into the "missing alt text" warning icon — to signal "yep, image uploaded successfully, but …"?
  2. What could aid discoverability is if there were more indicators. Examples:
    1. different outline color than the default blue when selected
    2. persistent outline color (i.e. also when not hovered or selected).
    3. make .image__alt-missing-error visually more prominent — I would suggest including the lowVision SVG that we/CKE5 already use to signal this is for alt text:
  3. Should either work or somehow convey to the user that this is not allowed (and why)
lauriii’s picture

Issue summary: View changes
FileSize
594.57 KB

I've worked on an improved UX for strongly encouraging alt text on images. The approach that I've implemented does following:

  1. Open image alt text form on the contextual balloon after uploading image
    1. If multiple images have been uploaded, form is opened for the last uploaded image
  2. If alt text is not added for the image, a warning message with text "Add missing alternative text"
  3. The message is a button. Clicking the button opens the alt text form for that image.
  4. While the alt text form is visible, the warning message of the selected image is hidden

Here's a screenshot of the current solution:

ckrina’s picture

+1 on a design perspective: it brings enough attention into the message and communicates clearly what needs to be done.

rachel_norfolk’s picture

I really like the design used.

I wonder - is the implementation of bringing the alert to the image expandable? For example, if I wanted to add another "this is needed" message, let's say we want to add a message saying a geolocation for the image is needed, would that be possible?

lauriii’s picture

I really like the design used.

Thank you! This is based on the Drupal Design System with some tips from @ckrina on how to implement it. 🎉

I wonder - is the implementation of bringing the alert to the image expandable? For example, if I wanted to add another "this is needed" message, let's say we want to add a message saying a geolocation for the image is needed, would that be possible?

The implementation here is quite opinionated and tightly coupled with this use case. Unfortunately, I don't see an easy way for us to provide this as an API, at least at the moment.

Something worth noting is that CKEditor 5 provides only a limited number of APIs like that. The additional APIs we provide as part of our integration with CKEditor 5 has been kept very limited.

The design could potentially be reusable if someone wants to implement a plugin like that, and the implementation of this issue could certainly used as an inspiration for that.

rachel_norfolk’s picture

The design could potentially be reusable if someone wants to implement a plugin like that, and the implementation of this issue could certainly used as an inspiration for that.

That’s good enough for me!

nod_’s picture

Will look at the code, some feedback on the UX for now.

Warning message position
Problem when the image is too narrow to contain the whole message:


It extends outside of the image

And when left aligned, it's partly hidden

When adding a Drupal media, it's not possible to make it decorative

Toolbar positioning shift
Pretty minor detail but was surprised:
When checking the "decorative image" checkbox the position of the toolbar is updated, while the toolbar is opened, unchecking the "decorative image" checkbox the toolbar expands and the little arrow ends up off-center.

Wim Leers’s picture

Status: Needs review » Needs work

Already marking Needs work for the UX, especially for When adding a Drupal media, it's not possible to make it decorative.

lauriii’s picture

Issue summary: View changes

Thank you for the feedback @nod_! 🙏

Warning message position

✅ This is already part of the remaining tasks

When adding a Drupal media, it's not possible to make it decorative

✅ Since the alt text entered for media images in the CKEditor 5 are only overrides, I believe that the status of decorative media images should be managed in the media UI. For that reason I think it's outside of the scope of this issue.

Toolbar positioning shift

✅ Added to the remaining tasks.

nod_’s picture

Code looks good to me, similar to chat ckeditor5 does already and the additional parts make sense where they are.

bnjmnm’s picture

One of the "remaining tasks" is

There isn't screenreader interface for this at the moment. We need to decide if we need one.

There needs to be something, but I also think it is fine to defer to a followup as long as it's marked stable. The changes in this issue are already quite complex, and the more we contain scope, the more likely we are to get high quality reviews & discussion both here and the followup.

Why I think something is needed: Because of the mandatory alt text approach in CKEditor 4, screenreader will know it is needed as part of the image addition process. It's not the most elegant AT experience for CKEditor 4 users, but it's impossible to NOT know alt text is missing.

Because alt text being needed is implicitly apparent to CK4 users, CK5's alt text enforcement at least needs a signal-boost to not be considered a regression. Because the implementations are different, the screenreader support needs to be different but the salience levels should be similar.

lauriii’s picture

Issue summary: View changes
lauriii’s picture

Issue summary: View changes
lauriii’s picture

Re #63: Are you recommending that we announce something on image upload? I guess the button inside the image widget already makes it apparent that alt text is missing from the image. Just trying to figure out what exactly is still needed.

bnjmnm’s picture

Re #63:

Are you recommending that we announce something on image upload? I guess the button inside the image widget already makes it apparent that alt text is missing from the image. Just trying to figure out what exactly is still needed.

That's probably the solution - announce on upload or (ideally also) pasting in an <img/> with an external src. The issue I see is that in CKEditor 4, even without any visual cues user is 100% guaranteed to know alt text is needed because it's part of the upload workflow. With CKEditor 5, the image must be navigated to for there to be a nonvisual missing alt text warning.

An announce on upload/paste seems like a good compromise between the CK4 "you know because it's mandatory" and the MR's current "you'll know if you come over and check". I'm open to other solutions that make the nonvisual warning more salient, but the upload/paste announce is one I'd 👍.

lauriii’s picture

I'm struggling to come up with a good announcement. How would the user know where the announcement is coming from? This is sort of starting to touch the same problem I mentioned in #22 that it's not straight forward to explain for the user where the missing alt text is happening unless we take the user on some sort of dialog.

The pasting use case is also a bit trickier and sort of its own problem space so I'm wondering if we could move that to a follow-up which would potentially not be stable blocking since that use case was never supported by CKEditor 4. In that issue we will have to add event listener for clipboard events that checks if the image has an alt text.

lauriii’s picture

Issue summary: View changes
bnjmnm’s picture

Re #68

I'm struggling to come up with a good announcement. How would the user know where the announcement is coming from?

I just tried this out and it seemed fine to me:
At the end of the xhr.addEventListener('load' in DrupalImageUploadAdapter._initListeners I added a Drupal.announce(`you uploaded ${file.name}, to set alt text or mark the images as decorative, perform these steps I don't want to type out in this proof of concept`);

The pasting use case is also a bit trickier and sort of its own problem space so I'm wondering if we could move that to a follow-up

Follow-up is fine! Even the upload part we're tackling would be fine as a follow-up, although it would likely be a stable blocking one.

Wim Leers’s picture

#67++ 😊

#68:

How would the user know where the announcement is coming from?

Drupal.announce(Drupal.t("A new image has been uploaded into the text editor for the Body field. Please assign alternative text to it.");

and

Drupal.announce(Drupal.t("3 new images have been uploaded into the text editor for the Body field. Please assign alternative text to it.");
lauriii’s picture

Status: Needs work » Needs review

Based on #70, moved the screen-reader announcement to a follow-up.

Wim Leers’s picture

Status: Needs review » Needs work
FileSize
9.3 MB

All the basic functionality works great and as expected. I did my best to break it, but could not. I believe this screencast best captures the essence of the UX — see attached screencast! 🤩🤩🤩🤩

The code largely made sense to me. I left a bunch of questions about code clarity, comments, and tests. This feels really close!

lauriii’s picture

There's one edge case which I had forgotten on the previous iteration which is captions. The caption impacts the size of the container and therefore also impacts the absolute positioning. Usually we would add additional wrapper but in this case it seems very tricky since that causes problems with CKEditor. We could workaround this by moving the button to the top when caption is enabled:

lauriii’s picture

Status: Needs work » Needs review
rachel_norfolk’s picture

I might be missing this in the backscroll somewhere but is there a reason the warning needs to appear at the bottom by default?

If it was at the top by default then we wouldn’t need extra code to move it around when a caption is added.

lauriii’s picture

There's also status icon displayed on the top right corner right after image has been uploaded to indicate that the image upload was successful. Integrating with that is also a bit challenging since we are talking about absolute positioned elements without knowing the exact dimensions (the width of the missing alt text button could change depending on translation).

rachel_norfolk’s picture

Ah - yeah, good point.

Wim Leers’s picture

Status: Needs review » Needs work

That is a huge leap forward — I don't think I'll have questions after this round :)

Wim Leers’s picture

There's currently two test failures:

  1. 1) Drupal\Tests\ckeditor5\FunctionalJavascript\ImageTest::testWidth with data set "Image resize with percent unit (only allowed in HTML 4)" ('33%')
    Failed asserting that two strings are identical.
    --- Expected
    +++ Actual
    @@ @@
    -'33%'
    +''
    
  2. 2) Drupal\Tests\ckeditor5\FunctionalJavascript\ImageTest::testWidth with data set "Image resize with (implied) px unit" ('100')
    Failed asserting that two strings are identical.
    --- Expected
    +++ Actual
    @@ @@
    -'100'
    +''
    

I was able to reproduce the second failure. Once. While my local machine was under high load. This makes me suspect this is a performance and hence timing-related failure.

I was able to reproduce both failures when I forced it into the background.

But to my knowledge, this was not happening until this MR. Which suggests that this MR is introducing a race condition?! 😬 @lauriii, any ideas where that could be happening?

Wim Leers’s picture

Interesting: I was able to trigger a similar failure in HEAD by increasing my machine's load. This time it crashed with:

There was 1 error:

1) Drupal\Tests\ckeditor5\FunctionalJavascript\ImageTest::testWidth with data set "Image resize with percent unit (only allowed in HTML 4)" ('33%')
Error: Call to a member function setValue() on null

… which means it was

$text_area = $page->find('css', '.ck-source-editing-area > textarea');

that was not waiting for the textarea to have appeared just yet.

So maybe the real problem here is that the switching into and out of the source editing area is what's A) slow, B) sensitive to race conditions?

Either way, it does seem that tackling that semi-random failure is out of scope? It's unclear whether this MR is causing a higher failure rate or whether that is simply because DrupalCI's performance characteristics happen to be different lately…

Wim Leers’s picture

Status: Needs work » Reviewed & tested by the community

I think this is RTBC — other than the annoying detail that tests are failing 😬

Still, already marking RTBC so that the core committer review process can start! (What I failed to mention in my last few comments is that I did another round of manual testing and could not find any problems whatsoever 👍)

Epic work here! 🤩🤩🤩🤩

Wim Leers’s picture

So clearly there was a race condition somewhere in the SourceEditing plugin. Both @lauriii and I were able to reproduce the failure locally under sufficiently high load, even without this MR, just with HEAD!

https://git.drupalcode.org/project/drupal/-/merge_requests/1622/diffs?co... solves this problem completely by avoiding relying on Source Editing.

This is now firmly RTBC :)

lauriii’s picture

  • bnjmnm committed c6d7b83 on 10.0.x
    Issue #3222757 by lauriii, Wim Leers, nod_, rachel_norfolk, mgifford,...

  • bnjmnm committed f26b632 on 9.4.x
    Issue #3222757 by lauriii, Wim Leers, nod_, rachel_norfolk, mgifford,...

bnjmnm’s picture

Committed to 10.0.x and 9.4.x. Added to the list of recommended 9.3.x backports when #3269651: Update Drupal 9.3.x to CKEditor 5 v34.0.0 along with other un-backported issues happens.

Prior to committing this, alt text in images was not enforced/encouraged in any way. Clearly that had to improve. We also realized we couldn't provide the exact experience offered by CKEditor4. We reached out to the wider community (including accessibility maintainers who weren't me) for input to come up with this solution.

How it was in CKEditor 4
In CKEditor 4, alt text was ostensibly mandatory, but this enforcement occurred only when uploading via the CKEditor image upload plugin, which is only one of several ways an image can be added. Copy/paste, and dragging-in are two other common ways to to this.

When this mandatory-alt-text form appears marking an image as decorative requires adding empty quotes to the alt field - and this is only apparent if someone notices that instruction in the form input description (something often and understandably ignored). Users may also enter gibberish into the field in order to continue with their work, resulting in a less accessible experience than had they omitted the use of alt entirely.

How it now works in CKEditor 5
The CKEditor 5 implementation is a little less opinionated, but equally, if not more accessible than CKEditor 4. Alt text is no longer Enforced, but it is very loudly Encouraged, and improves on the prior implementation in several ways.

  • It happens regardless of how the image is added. Upload, cut/paste, drag. There's really no way for just-Drupal to make it mandatory during image addition if all methods of addition are supported.
  • There is a dedicated "mark image as decorative" switch that hides the alt text field. This is now an intuitive step that can flow nicely into the modern content editor's fragile attention span.

We considered preventing save if alt text was missing but decided against for several reasons:

  • It would require an entirely new validation/message pattern that itself would be difficult to make accessible
  • No other CMS does this, and there's no evidence of them being criticized as a result. Overall there's no evidence of a demand for such a feature.
  • People may need to save a draft and haven't dealt with alt text yet.
  • Preventing on save could result in "gibberish alt text" behavior
  • Even as-is, it is more explicit about encouraging alt text than any other CMS researched

This is a huge improvement, and as people use it and identify things they'd like changed, the issue queue is there to listen.

bnjmnm’s picture

Status: Reviewed & tested by the community » Fixed
xjm’s picture

Version: 9.4.x-dev » 9.3.x-dev
Status: Fixed » Postponed

Postponing for backport after the v33 and v34 update.

catch’s picture

Status: Postponed » Needs work

v34 is in, so this is unblocked.

lauriii’s picture

Status: Needs work » Needs review
FileSize
71.46 KB
lauriii’s picture

lauriii’s picture

Status: Needs review » Reviewed & tested by the community

Marking #93 as RTBC since it was a straight forward reroll and it's passing all tests.

  • bnjmnm committed 1b83700 on 9.3.x
    Issue #3222757 by lauriii, Wim Leers, nod_, rachel_norfolk, itmaybejj,...
bnjmnm’s picture

Status: Reviewed & tested by the community » Fixed

Agreed that it is a straightforward backport. Everything looks good here so this is now in 9.3!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.