Problem/Motivation
The body field summary textarea indicates it has a description with an aria-describedby attribute, but the DOM id value points to a non-existent node. Here is the code:
<textarea class="text-summary form-textarea resize-vertical text-summary-processed" aria-describedby="edit-body-0-summary--description" id="edit-body-0-summary" name="body[0][summary]" rows="3" cols="60"></textarea>
This is a problem for users using a screen reader. Without a description, it is not apparent what the field is for.
To repeat:
- Ensure the WYSIWYG is enabled
- Add a description text
- Check the
<textarea> for the body and search for the aria-describedby which should point to the description ID
- Check if there is an id for the description or if it looks like
<div class="description">example</div
Proposed resolution
It seems like the description text for this field was simply not added or that the textarea should have an ARIA aria-labelledby attribute that points to the field label ID.
Remaining tasks
- Propose an initial patch.
- Review/fix initial patch.
Comments
Comment #1
jessebeach commentedComment #2
SGhosh commentedTested using ChromeVox screen reader. Tested on summary textarea of create new page form -
Qs -
* Will both the above attributes be required then?
* When nothing is given how is the screen reader reading the label
* For using these attributes the id of the element to be used has to be given; but label only has for attribute. Will we need to add id to label element to provide it as label attribute to textarea for use by screen reader?
Comment #3
SGhosh commentedComment #4
SGhosh commentedWrong comment no. in patch name - corrected.
Comment #5
mgiffordWhat's different between textarea_accessibility_by_screenreader-2126761-4.patch & textarea_accessibility_by_screenreader-2126761-2.patch
Seems like a simple fix, just adding:
+ $element['#attributes']['aria-labelledby'] = $element['#id'] . '--description';Comment #6
jviitamaki commentedComment #8
dsdeiz commentedI think he just corrected the patch file name.
Comment #9
dsdeiz commented4: textarea_accessibility_by_screenreader-2126761-4.patch queued for re-testing.
Comment #10
mgiffordOk, in that case, I'm not sure how adding a
$element['#attributes']['aria-labelledby']element is going to help as the problem that Jesse noted is that in$element['#attributes']['aria-describedby']there is a reference to an ID which doesn't existaria-describedby="edit-body-0-summary--description"We have to make sure that the DOM ID value
$element['#id'] . '--description'exists.Comment #11
tim bozeman commentedComment #12
tim bozeman commentedI don't really understand whats going on with $element['#id'] . '--description'
Doesn't that just add a string to the ID or is '--description' an actual flag? I changed it to $element['#description'] and now there is text showing up at least.
Comment #13
tim bozeman commentedI added aria-labelledby to #attributes and set it to $element['title']
Comment #14
mgiffordOk, I think that gets you this:
aria-labelledby, seems redundant as the label is already associated with the text area's ID.
For aria-describedby though you need to point to an ID. I think that the ID is supposed to be associated with the help text or description associated with the text area. At the moment this just has
<div class="description">...</div>and there is no ID. That's why there's an error.Comment #15
tim bozeman commentedHmm. I see. Hmmm. It looks like the description div now has an ID that matches what the aria-describedby is pointing to.
Maybe it was fixed in another issue? If not where's the error you speak of? :)
Comment #16
mgiffordThat's accurate for the summary. It's accurate for the body of the text without CKEditor. However with the WYSIWYG editor enabled, the ID isn't present.
The summary seems to be fine, however, the body doesn't.
Comment #17
jessebeach commentedI think this issue has magically resolved itself and cannot be closed as cannot reproduce. Here is the code currently in D8 head:
Note that the describedby attribute has an ID that points to the ID of the description element.
Comment #18
mgiffordThis issue might be fixed on the summary (which is why this issue was created), but is still broken on the body with the WYSIWYG enabled:
That could just be a new issue, but I think it is broken because of the WYSIWYG.
Comment #19
tim bozeman commentedIt looks like
<div class="description">more help text here.</div>was removed recently. On line 1350 of FormBuilder.php it checks if there is a descriptionSo I guess that it makes sense that the text area changed and doesn't have an 'aria-describedby' anymore.
<textarea placeholder="" cols="60" rows="9" name="body[0][value]" id="edit-body-0-value" class="text-full form-textarea resize-vertical" style="visibility: hidden; display: none;"></textarea>So how does one add a description to the text area?
Comment #20
tim bozeman commentedI see that the description for the edit-body-0-summary text area was added with
on line 70 of core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php
Whats next? Extend TextItemBase in a new file?
Comment #21
tim bozeman commentedComment #22
mgiffordYou can just add it to the content type here /admin/structure/types/manage/article/fields/node.article.body
If the descriptive text isn't there, then there's no need for the aria-describedby attribute. If it is added, then right now in Core the aria-describedby value is added to the textarea, but there is no ID added to the description.
Comment #23
mgiffordWhy don't textarea's use theme_form_element()? The help text for the textarea just doesn't appear when I echo code within it..
Comment #24
tim bozeman commented= D
Comment #25
mgiffordOk, what is theming the textarea? Where is this defined?
Comment #26
mgiffordComment #27
tim bozeman commentedI'm not too sure. In D7 I would check devel_themer. textarea.html.twig?
Cottser mentioned changing attributes should happen in preprocess. Does that sound like what we are going for to add the ID to the help text?
Comment #28
tim bozeman commentedThank you very much for walking me through this far mgifford!
I'm not too sure how to figure out where it is defined or whats theming it. I see that the 'help text' field is at admin/structure/types/manage/article/fields/node.article.body
When I debug I can see the field using text-format-wrapper.html.twig, but I'm not sure how to see what is theming or defining it.
Comment #29
mgiffordComment #30
mgiffordSo with text-format-wrapper.html.twig we need a 3rd variable so we can insert an ID. Right now whenever this template is called, there is just no way to include the ID:
<div class="description">{{ description }}</div>datetime has a similar issue.
Comment #31
tim bozeman commentedI added the attributes twig thingy to line 16 of text-format-wrapper.html.twig
<div class="description" {{ attributes }}>{{ description }}</div>and added attributes to line 68 of filter_theme() in filter.module.
Comment #32
mgiffordIt's an improvement, but this produces:
<div class="description" aria-describedby="edit-body-0--description">Body help text. What will happen to the description? PATCH</div>Rather than:
<div class="description" id="edit-body-0--description">Body help text. What will happen to the description? PATCH</div>aria-describedby has to point to the ID for the descriptive text.
Comment #33
star-szrThis should be:
<div class="description"{{ attributes|without('class') }}>See https://drupal.org/node/2240005 for more details since this is a recent change.
Or better yet we can add the 'description' class in a preprocess function in filter.module and just do:
<div{{ attributes }}>Comment #34
tim bozeman commentedI changed text-format-wrapper.html.twig to
<div {{ attributes }}>and added a preprocess function that changes the aria-describedby key to id and outputs
The text-full class was already in the array.
Comment #35
mgiffordI think that's good! Great job @Tim Bozeman.
Comment #36
mgiffordoops
Comment #37
tim bozeman commented@mgifford Thank you so much for walking me through that I learned a lot!
Comment #38
star-szrIt's not a typo, there should be no space before
{{ attributes }}, the leading space is inserted automatically. Other than that, looking good!Comment #39
tim bozeman commented-
<div {{ attributes }}>{{ description }}</div>+
<div{{ attributes }}>{{ description }}</div>Thanks Cottser! :D
Comment #40
star-szrWow that was super quick! :) Reviewing this again there are a few other things I noticed.
We'll need to update some of the docs in text-format-wrapper.html.twig:
And the preprocess docs could use a bit of love I think:
Why the '#' here? It would be nice to explain the unset() as well with a small inline comment.
Comment #41
tim bozeman commentedI added the docs and removed the #'s
There is a similar issue with datetime? Anyone got a link? Or should I start a new issue? :)
Edit: I didn't see an issue for datetime so I created one #2244923: The help text for datetime field needs an ID for screen readers.
Comment #42
mgiffordThis comment is a bit misleading:
// Remove aria-describedby attribute in favor of id.The aria-describedby has to point to an ID. It has to be unset because it shouldn't be showing up. Maybe:
// Remove aria-describedby attribute as as it shouldn't be visible here.Not sure.
Comment #43
tim bozeman commentedChanged the comment!
Comment #44
mgifford@Tim wanted to add that my comment was pretty trivial, thanks for re-rolling it though.
This looks great to me. Tests out fine in manual tests too.
Comment #45
star-szrMe again…
I think these docs look great but this is filter-caption.html.twig which I don't think should be involved here :)
Comment #46
tim bozeman commentedThat was not good. Thank you Cottser!
Comment #47
star-szrCool, thanks @Tim Bozeman! One more small thing then I'm happy to RTBC based on @mgifford's manual testing :)
Attributes should be initialized as an empty array, see other hook_theme() definitions which define 'attributes' and _template_preprocess_default_variables()().
Comment #48
Jalandhar commentedUpdating with change said in #46.
Comment #49
star-szr@Jalandhar thank you but you kinda stole the issue away from Tim :( it was assigned and he was turning around patches rather quickly over the past week or so. Usually we give people at least a few days if the issue is assigned to them, especially because this is not major/critical/beta blocking.
Anyway, thanks and looks good to me.
Comment #50
mgiffordIt's still @Tim Bozeman's.. He's been pushing this issue since December. I really don't think it matters who rolls the last patch.
Also thanks to @Jalandhar, @JesseBeach, @SGhosh & @Cottser for fixing this!
Comment #51
Jalandhar commented@Cottser: I really didn't mean to steal the patch from Tim Bozeman. I have just worked on the re-roll of the patch by seeing this patch under needs work issues, anyways the credit is for Tim Bozeman only. I am really sorry if I have done wrong.
My re-rolled patch might be a minor help for him....:)
Comment #52
star-szr@Jalandhar, don't worry. Just wanted to make sure you were aware. Onwards!
Comment #53
tim bozeman commented<3
Comment #55
mgifford48: body-field-summary-textarea-screenreader-id-2126761-48.patch queued for re-testing.
Comment #56
Jalandhar commentedComment #57
tim bozeman commentedComment #59
tim bozeman commented48: body-field-summary-textarea-screenreader-id-2126761-48.patch queued for re-testing.
Comment #60
mgiffordBad bot...
Comment #62
catchCommitted/pushed to 8.x, thanks!