Problem/Motivation
The required state is currently not set in the Accessibility Object Model (AOM) for the following fields in Drupal Core:
- Timestamp
- File
- Image
- Formatted text long
- Formatted text long sum
- Comment
- Checkboxes
- Radios
- Tableselect, multiple (using checkboxes)
- Tableselect, single (using radios)
For point 1-5 check out fields.mp4 and for point 6 checkout comments.mp4
This issue was initially only about the File field missing the required state, but it hasn't made much sense to create six separate issues about the very same objective, therefore it made more sense to extend the scope for this issue.
In regard to the original issue I've appended underneath the new problem/motivation section, it has to be noted that announcing a star is not necessarily helpful and sort of cryptic for screenreader users. There are #3568100: [PP-1] Avoid the announcement of the star for required fields in the aural interface for Claro and #3566851: [PP-1] Avoid announcing the star for required fields in the aural interface for Gin postponed on this issue that avoid the announcement of the star in the aural interface - we leave the announcement in until this issue is begin fixed to leave in at least some aural cue that might indicate these fields are required (even though on some even the star is not available/announced)
Original issue summary
Asterisks for certain fields are not announced by JAWS. As an example within the “Create Image” screen, the “Image Upload *” button is announced by JAWS as, “Image upload file upload edit browse…” instead of being correctly announced as e.g. “Image upload required file upload edit browse…”
The defect exists in IE 11 and Google Chrome v55.0.2883.87 m.
Expected result: All asterisks are expected to be announced by JAWS. For example required red asterisk is expected to be made available for JAWS to read with the associated form title e.g., “Image upload required file upload edit browse…”
Reference: Section 508, Part 1194.22, Paragraph (n).
Notes:
• This defect may exist elsewhere within the application.
• This defect exists on a screen that is not accessible via a keyboard. The tester was forced to use the mouse to access this screen, which is not acceptable for a JAWS user.
Steps to reproduce
- Create a content type and a
timestamp,File,Image,Formatted long text,Formatted long text with summary, andCommentfields. - Create a new node for that content type and check the aural interface with your screenreader of choice.
Proposed resolution
At the moment fields that have correctly set the required state in the AOM have the required and the required="required" attributes set on the input field in the DOM - the latter is a legacy relic of XHTML. Based on the discussion on Slack (https://drupal.slack.com/archives/C2ANFUGGG/p1768590644204559) with @cwilcox808, @mgifford, and @mherchel, as well as the feedback by @drupa11y and @kentr, the general consensus was to drop required="required". The support is good per https://a11ysupport.io/tech/html/required_attribute and https://caniuse.com/?search=required and it is also the recommended solution many knowledgeable folks in the a11y field agreed and provided feedback on in this article: https://css-tricks.com/demystifying-screen-readers-accessible-forms-best...
So the proposed resolution is just add the required attribute to the following fields:
- Timestamp
- File
- Image
- Formatted text long
- Formatted text long sum
- Comment
Adjusting the rest of the fields in Core that are already using required and required="required" should be handled in a followup issue.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | comments.mp4 | 310.88 KB | rkoller |
| #29 | fields.mp4 | 1.74 MB | rkoller |
| #26 | comment.mp4 | 423.36 KB | rkoller |
| #26 | nodeedit.mp4 | 2.02 MB | rkoller |
| #22 | Screenshot 2025-05-27 at 3.32.19 PM.png | 593.47 KB | mohit_aghera |
Comments
Comment #2
kershme commentedComment #4
findleys commentedThis issue appears to be specific to required file uploads. The required class is on the label, but not the input fields. The reader is reading the choose file button prior to file upload and the file name after file upload.
Comment #5
mgiffordThanks for the update.
Comment #6
avpadernoComment #7
andrewmacpherson commentedbugs are still eligible for 8.4.x patch releases.
Comment #8
andrewmacpherson commentedThanks @findleys ans @kershme, I've replicated this.
There's no programatically determined indication that a file field is required. The only indication is the red asterisk, from the
label.form-requiredclass.This relates to WCAG 1.3.1 Info and Relationships, and 3.3.2 Labels or Instructions, . Interestingly, WCAG 2.0 doesn't mention the HTML
requiredattribute, presumably because it was introduced by HTML5 and wasn't around when WCAG 2.0 was published. So there isn't a "common failures" document in WCAG for this problem. The most relevant document is probably ARIA2: Identifying a required field with the aria-required property which describes using the related aria-required property.Comment #9
avpaderno@#8 Yes, but first they are fixed on Drupal 8.5, and then back-ported to Drupal 8.4.
Comment #10
avpadernoComment #16
bskibinskiThis issue still exists in 9.3 for file/image upload fields.
First off, I think drupal should improve the way it displays the asterisk:
Improve 'required asterisks' in general
At the moment, drupal's default way of showing the asterisk is through CSS (through a pseudo :after element).
This in my opinion is already not great, because screenreaders can't 'see' it.
Solutions
Solution 1 - add text
A good 'simple' improvement would be to just add the text "required" and make that text 'visually-hidden', this way you can leave the old css asterisk as is.
Solution 2 - add svg
replace it with an SVG asterisk, with a aria-label="required" and title="required" (for a nice mouse over popup).
remarks
This would at least make the required part readable for screenreaders, so even if an input field lacks the proper 'required' attributes, at least the label will tell them it's a required field, which is already an improvement.
caveats
This could be a bit more difficult for conditionally set required fields (like through webforms).
Now, you can easily show/hide the asterisk by adding/removing one class through javascript.
My proposed solutions will only work for conditional fields, when you always render the required-icon/text in the twig file, and display:none them by default, to only show them when a field gets the required class.
Or, to set the text/icon through Javascript, but this seems more dirty to me.
but perhaps there are better solutions i didn't think off.
Add proper required attributes to file upload fields
The real issue is not fixed with my previous suggestion.
So adding the "required" & "aria-required="true"" would still need to be done for file uploads.
But as I understand, there is no good way to determine this programmatically (if i read the comments correctly), so that ability should be added to drupal core.
Comment #21
dcam commentedIf you need a workaround for this issue, then you can put this in your custom theme:
I'll see about fixing it properly in Drupal Core another time.
edit: Don't use this! It causes forms with required file fields to not be submitted properly. The form's page reloads with no errors on the page, in the site logs, or in the server logs. I'll have to try to find another solution.
Comment #22
mohit_aghera commentedTagging for initial review with the accessibility team.
I'll work on issues depending on the inputs from the team.
I'm in favour of using "aria-required: true" unless there aren't any other ways.
Currently when field is required, we have following markup in claro in standard profile.

Comment #23
mgiffordI do want to make sure that we are building on well researched patterns. There are a few like:
This is a common problem and we should be able to leverage a pattern which is both well tested and well established.
Comment #24
rkoller@katannshaw, @mgifford, @the_g_bomb, and myself discussed the matter back and forth for the last couple of days to weeks about how to tackle and, in particular, scope the problem at hand.
In summary we agree with most of the problems raised in this issue, but from our point of view it would be a reasonable step to chop the issue up, create an overarching meta issue, and have this issue rescoped and create a few additional follow up child issues alongside.
In regard to scope, it also has to be noted, during our testing it turned out, it is not only the file field affected, but also the image field, the formatted long text field and the formatted long text with summary field that are missing a required attribute.
In the following we would suggest three general steps how to chop up the problem - at least one of the steps might be subdivided even further.
1. Add the required attribute
We would advise to stay consistent with the field api in Core. Instead of going with
aria-required=“true”for the input elements for file and image fields, as suggested in #22, better go withrequired=“required”that is used on all the other input elements. Problem is fordivelements (formatted long & formatted long with summary) that approach probably won’t work, there thearia-required=“true”might be required.In regard to scope it might make sense to rescope this issue and make it solely about adding the
required=“required”attribute to the image and file field and open another issue for addingaria-required=“true”to the formatted long & formatted long with summary fields.Next, the following two issues should be postponed until step one is fixed and all field types in Core use a required attribute.
2. Improve the asterisks in the aural interface
In the aural interface for for example VoiceOver the announced text for a field with the label
plain textcurrently isplain text *, required invalid data, edit text, main.We are in line with #16 that the asterisk is potentially confusing for screen reader users. But instead of adding a visually-hidden “required” text snippet to the asterisk we would simply exclude and hide the asterisk from the aural interface. With the required attribute in place with step 1 completed the asterisk is now redundant information.
The fix could be worked on in the already existing #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0. As the proposed resolution, wrap the asterisk in a
spanaddingaria-hidden=“true”so it is hidden from screen reader users for all available field types while still visible for sighted users.3. Improve how required fields are communicated in general
As previously stated, required fields have a few inherent problems - Adam Silver outlined those in: https://adamsilver.io/blog/how-to-highlight-required-and-optional-form-f...
Our suggestion would be to open another follow up child issue, that will probably require a lot of discussions and testing with actual users, but as a discussion starter the following approach could be suggested.
In node edit forms, based on the number of required and optional fields, the group of fields that is smaller in number should get the
(required)or(optional)suffix appended to the corresponding field labels. That way it would be clearly communicated what the requirements for that node edit form are - the automatic approach. Another option might be to add a vertical tab to the edit page for a content type and provide the user options to set the to be discussed behavior of the node edit form in regard to required and options fields.The following video https://www.youtube.com/watch?v=mvIaUHr2i5U covers most aspects of that discussion. It includes the aspects of the article Adam Silver posted, and discusses https://www.nngroup.com/articles/required-fields/ as well as https://www.deque.com/blog/anatomy-of-accessible-forms-required-form-fie.... The arguments in the nngroup article argue for example against #3037446: Forms with required fields marked by asterisk do not have text explaining what the asterisk means a related issue that was raised during the discussions for this issue - providing some description for the asterisks is considered rather pointless according to the nngroup, since most users don’t read the instructions at the top of a form.
But looking at all those resources shows two things, that the current state of how required fields are handled in Drupal has room for improvement and that there might be no one-for-all solution. Either way the issue for step three will require a lot of discussion and user testing.
Comment #25
duaelfrThis plan sounds good to me.
Points 1 and 2 could be done quite quickly and would already be a nice win for accessibility.
Point 3 is really interesting to me. I'd love to have a global setting to configure that "required" or "optional" output, then be able to ultimately override that either in more specific config or even in the Form API.
Comment #26
rkollerufff after @jurgenhaas asked over in a followup issue #3566851: [PP-1] Avoid announcing the star for required fields in the aural interface on the gin queue if that issue should be postponed until #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0 i thought there wouldnt be no need since gin is overriding the css this issue is changing anyway. the more important issue would be this one since #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0 is now also removing the * from the aural interface. so it dawned on me we have to make sure that all the field in core have the required attribute. so i went ahead and created a content type, adding all the available fields and made each of them required. and it turned out there are more fields missing the programmatic required label. :(
1-6 see nodeedit.mp4 and 7 see comment.mp4
even though the link field has a programmatic required label that required label is burried in a wall of text, redundant text. so it is very unlikely someone is listening until the end and or is taking notice then.
so looking at the overall plan going forward. from my perspective the following would make sense:
fix this issue by only adding the programmatic required label. and either expand the scope adding the programmatic required label to the other fields listed or open dedicated issues for each of the listed fields. and postpone #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0 and #3566851: [PP-1] Avoid announcing the star for required fields in the aural interface until the programmatic required field label was added.
after those two steps are fixed, step 3 in #24 can be discussed and solved within a followup issue?
Comment #27
rkoller@duaelfr looking at the increased number of fields requiring a programmatic required label i wonder if it would be the better choice to move the removal of the star out of the MR in #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0 again and into a dedicated issue? cuz it is uncertain how long the addition of the programmatic required label not for one but 6 to 7 fields might take. and those are a blocker for #2921627: Do not use a CSS-only required marker in forms per WCAG 2.0 in the proposed plan in #26.
Comment #29
rkollerI've extended the scope to all the fields that have not the required state set in the AOM and updated the issue summary accordingly per previous discussions on Slack. I'Ve appended the original issue summary at the end of the new problems/motivation section. I've also added tags for SC 1.3.1 and SC 3.3.2 per #8. And due to the fact that both are level A criterias i've set the priority to major..
The only question I am uncertain about is which component to pick since the issue isnt only about the
Filefield anymore. Please adjust if anyone knows what the more appropriate component would be in this case.Comment #30
rkollerComment #31
rkollerComment #32
smustgrave commentedSomething will note there are probably dozens of related issues to this, I'm willing to bet.
Comment #33
smustgrave commentedTook a look during a11y-bugsmash meeting. I think this should be turned into a META with child issues per plugin. Each change will need test coverage so it'll be easier in smaller bits. Also summary should be super clear with only 1-2 sentences about what needs to be done.
Comment #34
kentr commentedField system?
Comment #35
kentr commentedI wonder whether adding the
requiredattribute alone will solve this for the date / time fields.I'm seeing that the timestamp and other date/time types already have
required="required"on their underlyinginputelements.I don't know how to check the AOM directly, but in Edge & Firefox I find that they are not announced in VoiceOver as "required". I also tried it with the simple
requiredboolean attribute and witharia-required="true".Here's a 'pen with different configurations, and a W3C test page for
aria-required.From what I can tell it, appears that there are several "classes" of the problem that need individualized solutions:
inputoftype="time"andtype="date".inputoftype="file".divwithrole="textbox".radioelements insideradiogroup.checkboxelements insidefieldgroup.required="required"that gets buried in the long field description.I don't know if it's the same as dividing this by plugin, but I suggest starting with dividing it into the problem classes.
Radios and checkboxes already have issues, which I moved to child issues here.
Also, it looks like core uses
required="required". For anything that we do with the HTMLrequiredattribute, I think we'll have to stick with that and just set the#requiredrender array property where needed.[edited for clarification]
Comment #36
rkollerAt first i thought this could be simply solved in a single issue, but revisiting this issue and reading through #35, i guess it was the right call by @smustgrave in #33 to tackle all the different cases individually. I went ahead and added the [meta] prefix to the issue title and best would be to open individual issues for the rest of the listed field types.
Comment #37
kentr commentedThere are also tableselect elements, which are essentially checkbox and radio groups formatted as rows in a table.
These might be simple variants that can be handled in the existing checkboxes and radios issues.
I don't know of any live examples for these in core, but they can be seen at these paths with the
form_testmodule enabled:/form_test/tableselect/multiple-true/form_test/tableselect/multiple-falseComment #38
rkollerin regard of checkboxes, each content list page (content types, block types, media types etc) are formatted as tables but none of them are required. and in regard to checkboxes i not even know a case that uses that table formatting. so if some action is necessary imho as simple variant in the existing checkbox and radio button issue might be enough (if necessary at all)?
by the way manually testing those two examples in the form_test module, that feels odd testwise if you interact by keyboard.
Comment #39
kentr commentedThere's a live example of a
tableselectelement with'#required' => TRUEin in the Locale module.That example removes the checkboxes from the form when there aren't any language updates available, so actually observing the
requiredbehavior appears to require having an installed language for which an updated translation file is available.I don't think it can be observed on
mainor other dev branches because there aren't any translation files available.These steps reproduced it for me:
10.5.10. I did this on a core dev site by checking out the tag withgit checkout 10.5.10and doing astandard installation with
drush si.$config['system.logging']['error_level'] = 'none';insettings.php(orsettings.local.php,settings.ddev.php, etc).localemodule./admin/config/regional/language/.11.3.10by doing a "normal" upgrade for an existing site. I did this on the same dev site by checkingout the tag with
git checkout 11.3.10and doing the normal upgrade process (database updates, etc)./admin/reports/translations.That results in an error message at the top, "Select a language to update.", and the checkbox in the "Afrikaans" row is marked as invalid.
However, AFAICT there's no other indication that a choice is required (visually, hidden, or in the AOM).
This is a simple example where it's pretty obvious that the form won't work without a language selected, but
tableselectis a standalone field type that can be added programmatically to more complex forms.I think we should include
tableselectfields in this plan for that Locale module example and for future-proofing. I still don't know if it will be fixed along with the other checkboxes / radios issues.Comment #40
rkollerufff kudos digging up that example! but not sure if i would add it to the existing radio button and checkbox issues? looking at the example in #39 this looks like a different scenario. i am not even sure if adding the required attribute to that table or checkboxes would be the right choice for the example in #39? one option that comes to mind might be disabling the update button as long as no available language is getting selected? (disabled and aria-disabled attribute, with the latter the button would remain tab- and announce-able). but however this scenario is getting solved i would open a dedicated issue instead of solving it under the existing checkbox or radio button issue. what do you think @kentr?
Comment #41
kentr commentedYeah, I don't think the
requiredattribute should be added to the table.I see a parallel with the checkboxes issue(s) because
requiredalso shouldn't be on the enclosingfieldset, and in #2950999-3: Checkboxes element missing "required" attribute it sounds like @andrewmachpherson is recommending to not addrequiredto the individual checkboxes:tableselectcan definitely have its own issue if that makes more sense.I'm just wondering if the solution is the same for
checkboxesandtableselect, and if the fix fortableselectcan be wrapped into #2950999: Checkboxes element missing "required" attribute by thinking of it as just another formatting of a group of checkboxes. It might automatically inherit whatever we do for checkboxes. I just don't know that off the top of my head.Comment #42
kentr commentedThat sounds like a great UX improvement.
Still, if there is no indication that at least one choice is required from the group of checkboxes, then wouldn't it be unclear to the user why the button is disabled?
Comment #43
rkollerAdding the newly created meta #3600851: [Meta] Set the invalid state for all fields in Core in the Accessibility Object Model (AOM) properly as a related issue
Comment #44
kentr commentedI think that Needs accessibility review can be removed because of #24 and subsequent posts.