Follow-up to #2152217: Remove theme_form_required_marker() from the theme system - use CSS instead

Updated as of #165.

Problem/Motivation

3 years ago, in #2152217: Remove theme_form_required_marker() from the theme system - use CSS instead, the community decided to remove the star (*) used to indicate that a form field is required from the source code to add it from the CSS. Initially, the issue was just about converting the theme function to a Twig template but changed quickly. The purpose of this change was to simplify theming and improve accessibility. The thing is that, according to WCAG, this is not as accessible as we thought.

References:

Steps to reproduce:

Standard cases
  1. Go to any page including a form with required fields (eg. /user/login)
  2. Disable CSS in your browser
With JavaScript states API

Note: This mimics the automated test.

  1. In settings.local.php, uncomment the line $settings['extension_discovery_scan_tests'] = TRUE;, or add that line to settings.php.
  2. Enable the form_test module.
  3. Go to form-test/javascript-states-form.
  4. Check the checkbox named "Checkbox trigger".
  5. Find the textfield named "Textfield required when checkbox trigger checked", and note the required marker (star / asterisk).
  6. Disable CSS.
  7. Find the textfield named "Textfield required when checkbox trigger checked" again.

Current result: the stars on field labels are absent and there is no other visual indication that the field is required

Expected result: there is still some visual indication about the status of the required field

Screenshots

With CSS Without CSS
Before patch  Before patch, with CSS  Before patch, without CSS
After patch  After patch, with CSS  After patch, without CSS

Proposed resolution

  1. Bring back markup, but use the string "(required)" instead of "*" (aka, an asterisk or star).
  2. Wrap the new markup in a span with both:
    • The hidden CSS class to avoid changing the current look of the existing sites.
    • aria-hidden to avoid screen readers to vocalize the content of the span, as it's already covered by the aria-required and HTML5 required attributes.
  3. Put that span inside form labels and other interactive elements to increase target size.
  4. Apply these changes to the following elements. In some cases this will result in duplication of the "(required)" string with the same on the child field labels, but this is acceptable.
    • All standard form element labels.
    • legend elements (inside fieldset).
    • summary elements (inside details).
    • The h4 element that precedes datetime fields.
    • The JavaScript states API (as a JavaScript theme function in core/misc/states.js).

    See options 1 and 2 below for details on the different proposed implementations.

  5. Update tests & add coverage as needed.

Implementation options

Remaining tasks

Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Create a patch Instructions Done #19
Update the issue summary Instructions Done
Apply changes to new Default Admin theme Done #116
Add automated tests Instructions Done
Draft a change record for the API changes Instructions Done #128
Update the MR to incorporate feedback from reviews Instructions Done
Update the MR to incorporate point #2 from #62.
Other element types in JavascriptStatesTest may need coverage.
Instructions Done #130
Refactor the $label.append(...) code in states.js into a JavaScript theme function (#62, point 5) Done #130
Manually test the patch Novice Instructions Done #19
Fix cases of missing space in name / label (#125).
The case displayed in #125 is probably caused by states.js.
Done #130
Manually test the patch, specifically regarding the JavaScript states API.
See the Steps to reproduce for details.
Novice Instructions Done #150
Add steps to reproduce the issue Novice Instructions Done #97
Embed before and after screenshots in the issue summary Novice Instructions Done
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards Instructions Done
Decide if we're preceding with Option 1 or Option 2.
Discussion starts at #154.
Done. Option 2 was chosen in #174

User interface changes

Visually nothing as long as you have your CSS enabled. Before / after screenshots for visual regression are below.

A new "(required)" mention will be present on form field labels, fieldset legends, and details summaries for people that do not have their CSS enabled.

API changes

None.

Data model changes

None.

Before / after screenshots

Before and after screenshots illustrating that this MR isn't introducing any regressions (per request in #62 point 4)

Claro

Olivero

Admin theme

CommentFileSizeAuthor
#184 media.jpg36.12 KBrkoller
#181 2921627-nr-bot_kr4z0jqn.txt91 bytesneeds-review-queue-bot
#171 2921627-nr-bot_by6gitmf.txt3.35 KBneeds-review-queue-bot
#168 2921627-nr-bot_kd8iqvne.txt91 bytesneeds-review-queue-bot
#162 2921627-160-login-form-translation-result-hebrew.png21.39 KBkentr
#160 interdiff.2921627-160.MR-12981-MR-15924.txt35.67 KBkentr
#158 2921627-158-user-edit-page-with-Hebrew-language-installed.png109.26 KBkentr
#156 rtl.jpg258.17 KBrkoller
#150 safari.jpg97.87 KBrkoller
#144 2921627-nr-bot_dt78hkdq.txt91 bytesneeds-review-queue-bot
#141 2921627-nr-bot_abofyn1r.txt91 bytesneeds-review-queue-bot
#132 2921627-nr-bot_h_4i3cib.txt91 bytesneeds-review-queue-bot
#125 2921627-125-missing-space-between-main-label-and-required-text.png23.1 KBkentr
#119 olivero_login_no_css.jpg46.2 KBrkoller
#119 olivero_login_css.jpg49.27 KBrkoller
#119 olivero_no_css.png501.73 KBrkoller
#119 olivero_css.png270.06 KBrkoller
#119 admin_no_css.png463.88 KBrkoller
#119 admin_css.png221.77 KBrkoller
#119 claro_no_css.png456.19 KBrkoller
#119 claro_css.png200.83 KBrkoller
#117 issue-2921627-117-before-after.admin_.png304.66 KBkentr
#117 issue-2921627-117-before-after.olivero.png275.24 KBkentr
#117 issue-2921627-117-before-after.claro_.png305.17 KBkentr
#114 2921627-114-with-and-without-css-side-by-side.png285.84 KBkentr
#107 fieldsets.jpg182.04 KBrkoller
#106 2921627-106.patch23.38 KBduaelfr
#98 gin.mp4478.08 KBrkoller
#98 olivero.mp4384.08 KBrkoller
#98 claro.mp4263.32 KBrkoller
#95 requiredOlivero.mp4409.89 KBrkoller
#95 requiredGin5.0.x.mp4416.42 KBrkoller
#95 requiredClaro.mp4353.51 KBrkoller
#92 2921627-92-10.6.patch25.85 KBduaelfr
#92 2921627-92-11.x.patch23.38 KBduaelfr
#90 2921627-89.patch23.75 KBduaelfr
#84 interdiff_81-84.txt10.45 KBranjith_kumar_k_u
#84 2921627-84.patch23.02 KBranjith_kumar_k_u
#81 2921627-81.patch22.62 KBgauravvvv
#75 interdiff_74-75.txt1.14 KBranjith_kumar_k_u
#75 2921627-75.patch28.29 KBranjith_kumar_k_u
#74 2921627-74.patch28.41 KBduaelfr
#71 reroll_diff_2921627_68-71.txt8.54 KBankithashetty
#71 2921627-71.patch28.43 KBankithashetty
#68 interdiff_63-68.txt1.95 KBvsujeetkumar
#68 2921627-68.patch28.15 KBvsujeetkumar
#63 2921627-63.patch27.33 KBsutharsan
#60 after-patch.png12.89 KBsulfikar_s
#60 before-patch.png10.57 KBsulfikar_s
#59 interdiff_54-59.txt8.13 KBvsujeetkumar
#59 2921627_59.patch27.22 KBvsujeetkumar
#58 interdiff_54-58.txt8.13 KBvsujeetkumar
#58 2921627_58.patch27.22 KBvsujeetkumar
#54 2921627-54.drupal.patch17.3 KBsutharsan
#54 interdiff-2921627-51-54.txt1.1 KBsutharsan
#51 2921627-51.drupal.patch17.45 KBsutharsan
#51 interdiff-2921627-50-51.txt1.21 KBsutharsan
#50 2921627-50.drupal.patch16.39 KBsutharsan
#47 2921627-47.drupal.patch16.38 KBmikelutz
#44 login_form_8.6.0-rc1.png25.56 KBweekbeforenext
#42 core_accesible_form_labels-2921627-42.patch16.38 KBduaelfr
#42 interdiff.2921627.40.42.txt834 bytesduaelfr
#40 core_accesible_form_labels-2921627-40.patch16.38 KBduaelfr
#40 interdiff.2921627.38.40.txt2.63 KBduaelfr
#38 core_accesible_form_labels-2921627-38.patch16.37 KBduaelfr
#38 interdiff.2921627.36.38.txt8.17 KBduaelfr
#36 core_accesible_form_labels-2921627-36.patch9.97 KBduaelfr
#36 interdiff.2921627.34.36.txt3.69 KBduaelfr
#34 core_accesible_form_labels-2921627-34.patch6.28 KBduaelfr
#34 interdiff.2921627.32.34.txt574 bytesduaelfr
#32 core_accesible_form_labels-2921627-32.patch6.84 KBduaelfr
#32 interdiff.2921627.19.32.txt4.92 KBduaelfr
#30 expedia-required-no-css-shows-text-alternative.png8.58 KBandrewmacpherson
#30 expedia-required-css-asterisk-with-text-alternative.png295.49 KBandrewmacpherson
#3 d8-install-db-no-css-required-not-indicated.png114.18 KBduaelfr
#16 core_accesible_form_labels-2921627-16.patch1.79 KBduaelfr
#19 core_accesible_form_labels-2921627-19.patch1.9 KBduaelfr
#19 interdiff.2921627.16.19.txt2.18 KBduaelfr
#19 before_w_css.png8.32 KBduaelfr
#19 before_wo_css.png8.46 KBduaelfr
#19 after_w_css.png8.32 KBduaelfr
#19 after_wo_css.png9.96 KBduaelfr

Issue fork drupal-2921627

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:

Comments

DuaelFr created an issue. See original summary.

duaelfr’s picture

Title: Remove theme_form_required_marker() from the theme system - use CSS instead » Drupal should not use full CSS required marker in forms according to WCAG 2.0
duaelfr’s picture

Issue summary: View changes
StatusFileSize
new114.18 KB

@andrewmacpherson did a screenshot of the installer without CSS.

mgifford’s picture

Thanks @DuaelFr - this is an interesting issue and one that we obviously didn't fully consider when making this change.

I think that part of this was the confidence that we are already providing a lot of semantic information for assistive technology users.

So in this case the semantics should be covered by both required="required" aria-required="true":
<input class="js-text-full text-full form-text required" data-drupal-selector="edit-title-0-value" id="edit-title-0-value" name="title[0][value]" value="" size="60" maxlength="255" placeholder="" required="required" aria-required="true" type="text">

It is also interesting that the text is a symbol '*' rather than a word like '(required)'. So the meaning is already symbolic in the Drupal 7 way of addressing this.

I am pretty sure that there hasn't been any testing done without any CSS, I do wonder what other errors we'll catch by doing so. I do wonder though if perhaps this is an overly generalized guideline. Are people finding this a barrier? Is disabling CSS still relevant? It's probably more common to disable JavaScript, but there's lots that you can't do in any modern system without enabling it.

Are people in D8 theming the required element more now? Would everyone just be as happy if we'd kept it like we did in D7?

duaelfr’s picture

Since screen readers are already using the aria-required and the html5 required attributes to vocalise the mandatory status of the field, anything we may add in the markup should be marked as aria-hidden and speak: none to avoid the noise. Given that, we could just go back to the exact same markup than D7 which used <span class="form-required" title="This field is required.">*</span>. This way, themers could still hide the common star and use CSS to put their own required style. We keep accessibility AND themability.

(IMHO, we should consider to use another class on this span that could be easier to target than this generic one.)

andrewmacpherson’s picture

Why speak: none? aria-hidden should be enough to hide it from AT.

I can't find any info about speak:none implementation. I'd forgotten about the CSS speech properties. I don't think I've heard them being recommended any time recently.

andrewmacpherson’s picture

How about just "required", to keep the wording short?

mgifford’s picture

So we could just add something like this:

<label for="edit-account-name" class="js-form-required form-required">Username <span class="hidden">(required)<span></label>

So that if there is no CSS, the HTML would look like "Username (required)". If CSS is read then it would be hidden. No need to use any aria-hidden elements at all.

That work?

duaelfr’s picture

IMHO you can use a screen reader AND have no CSS so aria-hidden is required :/

mgifford’s picture

Yes, but in the case of a screen reader user disabling CSS they would still get very clear verification that this was a required field and should sound like - "Username (required)". I'm not sure what the aria adds. If CSS is disabled they wouldn't get the '*' but they would get the text '(required)' which is good if not better.

duaelfr’s picture

@mgifford The thing is that screen readers are already translating aria/html5 attributes to something. We need to hide this new string from them in any case to avoid a double indication. To summarize, we would need something like:
<label for="edit-account-name" class="js-form-required form-required">Username<span aria-hidden="true" class="hidden"> (required)<span></label>

Doing this way:

  1. users without screen reader and with CSS won't notice any change (span hidden and :after maintained on the label)
  2. users without screen reader and without CSS are going to see the "(required)" string appended to the label
  3. users with screen reader and with CSS are going to hear the label then the required sentence given by the aria-required attribute of the targetted field but not the content of the span (class hidden => display none)
  4. users with screen reader and without CSS are going to hear the label then the required sentence given by the aria-required attribute of the targetted field but not the content of the span (aria-hidden attribute)
andrewmacpherson’s picture

#11 is on the right track.

I think it should work well for sighted screen reader users too. With CSS they will see an asterisk, and hear "required". Without CSS they see and hear "required" (in English, anyway).

There might a localization issue here. What if an operating system or screen reader localization announces the required attribute using one phrase, but Drupal localizes "required" as a different phrase? Like the difference between "mandatory" and "compulsory". I've never used a screen reader in any language other than English, so I don't know. It's beyond our control though.

A minor point: the span doesn't need to be inside the label - it won't form part of the accessible name for assistive tech either way. For all the scenarios in #11, the following pattern also works:

<label for="edit-account-name" class="js-form-required form-required">Username</label><span aria-hidden="true" class="hidden"> (required)<span>

The difference between the two is that in #11 the word required is clickable, but in this version it isn't clickable.

duaelfr’s picture

I think it's important to have it clickable. The wider the clickable area is, the more accessible the form is for people that are not necessarily click-snipers. :)
Plus, I feel it's more complicated to pur it outside the label (#suffix ?) than to append it in the label.

andrewmacpherson’s picture

I don't mind either way, so let's put the span inside the label as a safer default.

In D8 I think this goes in form-element-label.html.twig with no need for FAPI #prefix. Themers can still move it outside the label, or move it up to the form-element.html.twig template if they like. Something like:

{% if title is not empty or required -%}
  <label{{ attributes.addClass(classes) }}>{{ title }}{% if required %} <span class="hidden" aria-hidden="true">{{ "(required)"|t }}</span>{% endif %}</label>
{%- endif %}

We should probably include a comment to document why it's there for accessibility.

mgifford’s picture

Coming along nicely! @andrewmacpherson & @DuaelFr

duaelfr’s picture

Status: Active » Needs review
Issue tags: +aria, +WCAG
StatusFileSize
new1.79 KB

Here is a patch to trigger the testbot.
I tried to find some place in core where the label render is tested but I found nothing. We are probably going to need to extend the coverage.

andrewmacpherson’s picture

Status: Needs review » Needs work
Issue tags: +stable, +Classy, +Needs manual testing

Thanks DuaelFr. The approach in patch #16 looks good, does what we discussed so far.

However we're not normally allowed to change templates in Stable and Classy themes during minor releases. Tagging for Stable and Classy maintainers - we've made changes to Stable to fix accessibility bugs before, so maybe this will qualify. Otherwise, we'll have to copy the Classy template to Bartik and Seven, and leave the Stable and Classy templates unchanged.

Nitpick: there's an extraneous space here we could eliminate. The one between the opening SPAN and the opening twig {{

<span aria-hidden="true" class="hidden"> {{ '(required)'|t }}</span>

The templates could be more readable if we split the "if required / endif" accross several lines, and used the whitespace collapsing form of braces: {{- if required -}}. See Whitespace control in the Twig manual.

Before going ahead with this, it would be good to test with a wide variety of browser + screen reader combinations. Screenshots of with and without author CSS applied will help here too.

andrewmacpherson’s picture

If we aren't allowed to change Stable/Classy, a change record will be a good way to recommend this approach for contrib/custom themes.

duaelfr’s picture

Status: Needs work » Needs review
Issue tags: -Needs manual testing
StatusFileSize
new9.96 KB
new8.32 KB
new8.46 KB
new8.32 KB
new2.18 KB
new1.9 KB

#17: I'm not sure about removing this space. The purpose is that people that browse without CSS should be able to read the label properly so we need a space to separate the label from the required mention. But, people that use CSS shouldn't have a lonely space at the end of their label for front-end-sake reasons. That's why I included this space in the span, the same way it's done for the "read more" link for example.

Here is a new version, aimed for template readability. I did some manual testing and the markup is exactly the same as the one in the #16's patch.

Markup

Before patch:
<label for="edit-name" class="js-form-required form-required">Username</label>

After patch:
<label for="edit-name" class="js-form-required form-required">Username<span aria-hidden="true" class="hidden"> (required)</span></label>

Screenshots

With CSS Without CSS
Before patch  Before patch, with CSS  Before patch, without CSS
After patch  After patch, with CSS  After patch, without CSS
duaelfr’s picture

Issue summary: View changes

Updated IS to include the tasks table, the screenshots and update the proposed solutions.

andrewmacpherson’s picture

Overall, the progress is looking great!

The extra space - ignore me. Now I see that only one of those spaces is actually output. That's fine, the output is correct.

We're still updating Stable and Classy templates though. I'm expecting the front-end framework managers will say no to that.

duaelfr’s picture

I hope they won't as these changes has absolutely no visual effect and they are important for a11y :/

opi’s picture

Why use .hidden class and not .visually-hidden ?

duaelfr’s picture

Because we need that string to NOT be read by screen readers. They already inform their users that the field is required because of the aria-required and required html attributes.

andrewmacpherson’s picture

Re: #23 and #24 - This is about avoiding verbosity in assistive tech, e.g. screen readers announcing "required" twice. The use of aria-hidden="true" is sufficient to ensure that span is hidden from AT, regardless of whether author CSS gets applied or not. So in this sense it doesn't really matter whether we use .hidden or .visually-hidden.

I think we should stick with .hidden for a couple of reasons:

  1. .hidden will effectively hide it from legacy browser/AT combinations which don't support aria-hidden, but .visually-hidden won't.
  2. .hidden is a much simpler (safer) implementation than .visually-hidden. It just uses display:none instead of all the properties needed for the 1px clip technique. Note that the .visually-hidden CSS itself needs ongoing review for nest practice. (See #2819823: CSS clip deprecated - .visually-hidden needs an update?.)
andrewmacpherson’s picture

We'll need to address this in fieldset.html.twig too, to achieve the same effect for required FAPI radios and checkboxes.

Some core forms where you test this:

  • Enable the Book module. Visit admin/structure/book/settings, which has required '#type' => 'radios' and '#type' => 'checkboxess'.
  • Enable the experimental Content Moderation module. The Add/Edit Transition form has required text, radios, and checkboxes. Visit admin/config/workflow/workflows/manage/editorial/add_transition.
andrewmacpherson’s picture

Status: Needs review » Needs work
andrewmacpherson’s picture

The patches so far have modified templates in Stable and Classy. We'd like to know if this will be allowed, or whether to update Seven and Bartik instead.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andrewmacpherson’s picture

I noticed a similar pattern in the wild, on Expedia's forgot-password form.

Here's a screenshot of the form and markup, from Firefox's dev tools. It's not exactly the same as proposed here, but works on similar lines. The main difference is that they are using a visually-hidden approach to the "required" text hint, and are not using aria-hidden. A screen reader says the word "required" twice; from the label text, and from the required HTML attribute.

Screenshot of Expedia's labels for required field, with a visually hidden text alternative for the red asterisk.

Without CSS, the label reads "Email addressrequired", without any space between words. Not bad, but our patch is already doing better:

Expedia's required field label with CSS turned off. There is no space between the words address and required.

I'm glad to see other people are thinking along the same lines as this issue. The patch here is a bit higher quality than Expedia's implementation, in my view.

duaelfr’s picture

Assigned: Unassigned » duaelfr
Issue tags: +DevDaysLisbon

Starting to work on #26

duaelfr’s picture

Assigned: duaelfr » Unassigned
Status: Needs work » Needs review
StatusFileSize
new4.92 KB
new6.84 KB

While fixing fieldsets, I thought about details elements too.

Status: Needs review » Needs work

The last submitted patch, 32: core_accesible_form_labels-2921627-32.patch, failed testing. View results

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new574 bytes
new6.28 KB

I forgot I had to patch for 8.5 first so Seven does not have the details.html.twig template yet.

Status: Needs review » Needs work

The last submitted patch, 34: core_accesible_form_labels-2921627-34.patch, failed testing. View results

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new3.69 KB
new9.97 KB

New patch that fixes tests and extends the issue to the datetime wrapper that I forgot before.

Status: Needs review » Needs work

The last submitted patch, 36: core_accesible_form_labels-2921627-36.patch, failed testing. View results

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new8.17 KB
new16.37 KB

I simplified the failing test assuming that fieldsets labels were tested elsewhere.
I added some coverage for our new markup in fields, fieldsets and wrappers.

I did not find tests for datetime_wrapper so it stays out of coverage (maybe we should consider not altering these templates).

Status: Needs review » Needs work

The last submitted patch, 38: core_accesible_form_labels-2921627-38.patch, failed testing. View results

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new2.63 KB
new16.38 KB

Let's try this way!

Status: Needs review » Needs work

The last submitted patch, 40: core_accesible_form_labels-2921627-40.patch, failed testing. View results

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new834 bytes
new16.38 KB

I know, I should have a local env for testing but I don't for now :/

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

weekbeforenext’s picture

StatusFileSize
new25.56 KB

Just tested core_accesible_form_labels-2921627-42.patch on Drupal Core 8.6.0-rc1 and it looks like it's working.

Login form showing the (required) markup added by the patch.

mikelutz’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
kostyashupenko’s picture

Issue tags: -Needs reroll

on my side i can apply #42 patch agains 8.6.x branch

mikelutz’s picture

Version: 8.6.x-dev » 8.8.x-dev
Status: Needs work » Needs review
StatusFileSize
new16.38 KB

Re-rolling this for 8.8

pcate’s picture

Will this patch apply the correct markup when the required attribute is toggled via the JS states API?

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

sutharsan’s picture

StatusFileSize
new16.39 KB

Re-roll #47 patch for latest 8.9.x

sutharsan’s picture

StatusFileSize
new1.21 KB
new17.45 KB

This patch makes 'required' #states add the right markup.

The last submitted patch, 50: 2921627-50.drupal.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 51: 2921627-51.drupal.patch, failed testing. View results

sutharsan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.1 KB
new17.3 KB

Under certain conditions the marker gets added multiple times.

Status: Needs review » Needs work

The last submitted patch, 54: 2921627-54.drupal.patch, failed testing. View results

andrewmacpherson’s picture

Bumping to major, because some of the relevant WCAG success criteria are at level A. In particular, the presence of the "required"/asterisk counts as "3.3.1. labels and instructions". If you don't know it's required, you don't have full instructions.

I was chatting with @rainbreaw about another potential use for this is in Windows high-contrast mode. Instead of trying to get an asterisk to display in :after, Windows high-contrast mode could use the actual required text (i.e. don't hide it).

andrewmacpherson’s picture

Priority: Normal » Major
Issue tags: +Bug Smash Initiative
vsujeetkumar’s picture

Status: Needs work » Needs review
StatusFileSize
new27.22 KB
new8.13 KB

Fixed test, Please review.

vsujeetkumar’s picture

StatusFileSize
new27.22 KB
new8.13 KB

Please ignore my previous patch, fixed test, Please review.

sulfikar_s’s picture

StatusFileSize
new10.57 KB
new12.89 KB

#59 , I've applied this patch and is working properly. I've attached the before and after screenshots below.
Before patch,
before-patch

After patch,
after-patch

sulfikar_s’s picture

Status: Needs review » Reviewed & tested by the community
lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs manual testing
  1. +++ b/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php
    @@ -240,7 +240,7 @@ public function testDateField() {
    -    $field_label = $this->field->label();
    +
    
    @@ -249,7 +249,7 @@ public function testDatetimeField() {
    -    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend/text()', NULL, 'Fieldset and label found');
    
    @@ -413,7 +413,7 @@ public function testDatelistWidget() {
    -    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', NULL, 'Fieldset and label found');
    
    +++ b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
    @@ -71,7 +71,7 @@ public function testDateRangeField() {
    -      $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +      $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', NULL, 'Fieldset and label found');
    
    @@ -298,7 +298,7 @@ public function testDatetimeRangeField() {
    -    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', NULL, 'Fieldset and label found');
    
    @@ -477,7 +477,7 @@ public function testAlldayRangeField() {
    -    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', NULL, 'Fieldset and label found');
    
    @@ -662,7 +662,7 @@ public function testDatelistWidget() {
    -    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
    +    $this->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', NULL, 'Fieldset and label found');
    

    Why do we need these changes?

  2. +++ b/core/misc/states.js
    @@ -356,9 +356,14 @@
    +          if (!$label.find('.js-required').length) {
    +            $label.append($('<span class="js-required hidden" aria-hidden="true">' + Drupal.t('(required)') + '</span>'));
    +          }
    ...
    -        $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required');
    +        $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required')
    +          .removeClass('js-form-required form-required')
    +          .find('.js-required').remove();
    

    Can we add test coverage for this?

  3. We need to apply these changes to stable9 too
  4. We should do manual testing and screenshots on all core themes to ensure there are no regressions
  5. +++ b/core/misc/states.js
    @@ -356,9 +356,14 @@
    +            $label.append($('<span class="js-required hidden" aria-hidden="true">' + Drupal.t('(required)') + '</span>'));
    

    We should add a theme function for this

sutharsan’s picture

Version: 8.9.x-dev » 9.2.x-dev
StatusFileSize
new27.33 KB

Rerolled the patch for 9.2.x

sutharsan’s picture

Status: Needs work » Needs review

Status to 'Needs review' to verify the reroll did not introduce errors.

duaelfr’s picture

The patch applies on 9.3 and still does what's expected.
What are the next steps to move this forward?

gauravvvv’s picture

Issue tags: +Needs reroll

This patch needs Reroll, as it has changes in /core/misc/states.js file but /core/misc/states.es6.js file is not updated.

Update es6 file then compile the code with yarn.

wim leers’s picture

Status: Needs review » Needs work

For #66.

vsujeetkumar’s picture

Status: Needs work » Needs review
StatusFileSize
new28.15 KB
new1.95 KB

Addressed #66, Please have a look.

duaelfr’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs manual testing, -Needs reroll

Looks good to me.
All comments have been addressed.
Patch passes all tests and fixes the issue.
Let's get it commited!

quietone’s picture

Version: 9.2.x-dev » 9.3.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

Bug fixes are against the latest version and the patch does not apply to 9.3.x. :-(

ankithashetty’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new28.43 KB
new8.54 KB

Rerolled the patch in #68, thanks!

Status: Needs review » Needs work

The last submitted patch, 71: 2921627-71.patch, failed testing. View results

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.

duaelfr’s picture

Status: Needs work » Needs review
StatusFileSize
new28.41 KB

Rerolled for 9.4

ranjith_kumar_k_u’s picture

StatusFileSize
new28.29 KB
new1.14 KB

Fixed CS error.

Status: Needs review » Needs work

The last submitted patch, 75: 2921627-75.patch, failed testing. View results

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mgifford’s picture

gauravvvv’s picture

Status: Needs work » Needs review
StatusFileSize
new22.62 KB

I have attached the patch for 11.x-dev. As in the earlier patch #75, Classy, stable and bartik were updated. which are no longer part of core. I have updated the latest themes. please review

Status: Needs review » Needs work

The last submitted patch, 81: 2921627-81.patch, failed testing. View results

mgifford’s picture

Alternatively, there's this approach https://adamsilver.io/blog/how-to-highlight-required-and-optional-form-f...

Just mark the optional fields. This would be a pretty huge change in the forms design though. Definitely a major release change, but D11 could be it.

ranjith_kumar_k_u’s picture

StatusFileSize
new23.02 KB
new10.45 KB

Removed some unrelated changes and added new tests

ranjith_kumar_k_u’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

This is having to update existing templates. Is that needed?

If there really is no other way then a change record will be needed.

mgifford’s picture

Issue tags: +high contrast

Adding reference to Windows High Contrast Mode.

duaelfr’s picture

Issue tags: +Needs change record

#86: yes we have to update existing templates or the issue won't be fixed. Adding the tag.

duaelfr’s picture

StatusFileSize
new23.75 KB

Rerolled #84 on the last 11.x commit in a MR.
Here is the patch for composer.

This issue still needs a Change Record. Is there a native english speaker that could handle this?

kentr’s picture

Looks like STR is still needed.

Adding Novice tag so novices can find this for those todo items in the IS.

Are tests still needed, or can that todo item be marked as done?

This point about WHCM (aka, forced-colors) by @andrewmacpherson in #56 hasn't been addressed. Is that intentional?

I was chatting with @rainbreaw about another potential use for this is in Windows high-contrast mode. Instead of trying to get an asterisk to display in :after, Windows high-contrast mode could use the actual required text (i.e. don't hide it).

duaelfr’s picture

StatusFileSize
new23.38 KB
new25.85 KB

Just rerolled MR on latest 11.x
Patches attached for composer

kentr’s picture

It looks like point #4 in #62 by @laurii hasn't been addressed. I don't see the screenshots from all core themes, at least. I'd say Gin should also be tested b/c it's in CMS and going into core.

We should do manual testing and screenshots on all core themes to ensure there are no regressions

Did the other points get addressed? I didn't see a reference to that comment in subsequent changes.

prudloff’s picture

Issue tags: +Needs screenshots
rkoller’s picture

StatusFileSize
new353.51 KB
new416.42 KB
new409.89 KB

From a manual testing standpoint this looks good across themes - tested in Claro 11.x, Gin 5.0.x, and Olivero 11.x. Instead of screenshots I went with short videos to compare with and without CSS to illustrate the visual output as well as the output of the the aural interface.

The only detail I wonder is something we've raised in #2852874-24: [Meta] Set the required state for all fields in Core in the Accessibility Object Model (AOM) (see point 2). As you can see and hear in the three videos, the star is getting announced in the aural interface alongside the announcement of the required attribute, strictly speaking that is redundant information - basically distracting noise. so i wonder if it would make sense to fix that detail within the scope for this issue? cuz the linked issue is only about the file field type and would have required a followup issue for in general anyway? or should it be moved to a dedicated followup?

mgifford’s picture

Issue tags: -Needs screenshots

I don't think we need screenshots any more, as the video @rkoller produced should be fine

We still need:

  • Needs change record
  • Needs steps to reproduce
duaelfr’s picture

Issue summary: View changes
Issue tags: -Novice, -Needs steps to reproduce

Updated the IS to add steps to reproduce.
Rerolled the MR on the last 11.x.
Added a fix to remove the "star" from aural output using the alternative text capability of the content CSS attribute.

This last fix would need a double check because it applies on fieldset labels too. As they are not marked as required by an HTML attribute, we might need to keep the aural output on these.


The issue still needs a change record (I'm not a native speaker, so I don't feel comfortable with that task)

rkoller’s picture

StatusFileSize
new263.32 KB
new384.08 KB
new478.08 KB

awesome thanks so much @duaelfr for the fast incorporation of that additional fix! i did another round of manual testing and recorded again for claro, olivero, and gin in safari 26.2 on macos 26.2 and in addition to that i also tested in the latest version of firefox and edge - using drupal 11.x and for testing with gin, gin 5.0.x with gin_toolbar installed.

claro and olivero look perfect to me in testing and the recorded videos. for firefox and edge i had the exact same results. perfect from my point of view. the only thing in gin the latest changes in regard to the star excluded from the aural interface are not available (the rest of the fixes still are still there as you can see ). not sure if something is missing for this MR or in case of the exclusion of the star from the aural interface an additional fix in gin would be necessary?

kentr’s picture

There were some random test failures that passed when re-run. Pipeline is green.

@rkoller

in gin the latest changes in regard to the star excluded from the aural interface are not available (the rest of the fixes still are still there as you can see ). not sure if something is missing for this MR or in case of the exclusion of the star from the aural interface an additional fix in gin would be necessary?

AFAICT that star comes from Gin's CSS (from a quick inspection in the browser with Gin 5.0.10).

rkoller’s picture

ah nice thanks! so if the star comes from gin that means a followup in the gin queue would be necessary to get en par with claro and olivero. then this issue would be good to go, isnt it?

kentr’s picture

@rkoller

so if the star comes from gin that means a followup in the gin queue would be necessary to get en par with claro and olivero. then this issue would be good to go, isnt it?

I agree that a followup for Gin is needed.

If you create the issue and the STR, I'm happy to add a screenshot that shows the CSS for this MR being overridden by Gin. I'm also happy to detail that in the proposed resolution, if that's helpful.

rkoller’s picture

@kentr i've opened #3566851: [PP-1] Avoid announcing the star for required fields in the aural interface . feel free to update the issue summary in case i've missed anything or phrased it in a to complicated manner. and at first i thought it might be good to postpone the followup on this issue but strictly speaking it could run in parallel if gin is overriding Claro CSS anyway?

rkoller’s picture

ok after quite a few discussions with @kentr and @mgifford we came up with the following approach. first a bit of context. this issue would be ready to go. problem is due to the introduction of the fix for removing the start from the aural interface based on my suggestion in https://git.drupalcode.org/project/drupal/-/merge_requests/12981/diffs?c... this issue would be blocked by #2852874: [Meta] Set the required state for all fields in Core in the Accessibility Object Model (AOM). by removing the star fields that dont have a programmatic required label would be unidentifiable for screenreader users. :( and it turned out in my testing that not only the field is missing the required attribute but also:

  • timestamp
  • formatted text long
  • formatted text long sum
  • image
  • comment

so our consensus was the following:

so to summarize the sole step relevant for the current issue is roll back https://git.drupalcode.org/project/drupal/-/merge_requests/12981/diffs?c... , do a last recheck, finish the change record, and then this issue should be ready for RTBC imho- apologies for the back and forth :(

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

duaelfr’s picture

Status: Needs work » Needs review
Issue tags: -stable, -Classy
StatusFileSize
new23.38 KB

MR rerolled on main branch.
Last commit reverted as asked in #104
Patch attached for composer.

rkoller’s picture

StatusFileSize
new182.04 KB

@duaelfr. thank you for reverting the last commit and apologies again for the back and forth. i just went ahead and retested the latest state of the MR. i've noticed one detail I haven't thought of in my previous test that raises one question. I have tested now a node edit form that contained a file and an image field around others that all were set to required. those fields are wrapped in field sets and the label of those field sets have stars too. The question is should those fieldset labels also replace the star with (Required)? At the moment only the star is not displayed anymore with CSS unavailable:

two browser windows next to each other on the left a node edit form with css available on the right without

smustgrave’s picture

Status: Needs review » Needs work

Appears to have some test failures.

Also will need a change record for the template changes.

Thanks!

kentr’s picture

I'll look into the test failures.

kentr’s picture

Issue summary: View changes
kentr’s picture

Issue tags: +Needs tests

The test failures in the previous pipeline were random.

As part of a rebase, I omitted core/modules/contact/tests/src/Functional/ContactSitewideTest.php in the original patch because it has since been removed in main.

Concern regarding tests:

#38 says

I did not find tests for datetime_wrapper so it stays out of coverage (maybe we should consider not altering these templates).

However, the MR has changes to several instances of datetime-wrapper.html.twig.

Some of them were added in #84, but I can't tell from the patch if it adds coverage directly related to datetime-wrapper.html.twig.

Looking into it further, but for now +Needs tests.

kentr’s picture

Issue summary: View changes

Looks like the changes need to be applied to the new Admin theme.

I will look into that, also.

kentr’s picture

Other concerns:

1. Regarding fieldset (#104 #107) and the file and image fields in the screenshots

Currently, in Claro, those aren't fieldset elements. They're details / summary elements.

However, the MR does add the "(required)" text for fieldset elements.

So the question is, do we actually want that for fieldset elements? Because actual labels for individual fields also have "(required)".

I'm seeing this also on required Datetime fields in the Stark theme, which uses the base system template that arbitrary themes might use if they don't override it.

2. Regarding datetime-wrapper.html.twig

Per #111, several instances of datetime-wrapper.html.twig are modified.

These changes are evident with required Timestamp fields, again in Stark theme.

To me, the change creates a problem. It adds the "(required)" text to h4 elements above the actual input fields, and the fields themselves also have "(required)". So, my thought is that datetime-wrapper.html.twig should not be modified for this issue.

What are thoughts on these points?

[edited to fix typos & improve formatting]

kentr’s picture

Here's a side-by-side screenshot of required datetime, timestamp, and file fields with and without CSS in Claro.

Now it makes more sense why the required marker (aka the asterisk, or "star") was added for the legend and the h4 in the datetime wrapper: the individual field labels are visually hidden.

Olivero and Admin (the theme formerly known as Gin, or TTFKAG) also do this.

However, since the individual fields do have the text "(required)", as seen in the right side of the screenshot, it seems unnecessary to also add "(required)" to the legend and the h4 in the datetime wrapper.

kentr’s picture

Disregard my comments about changing fieldset.html.twig and datetime-wrapper.html.twig. I had forgotten about #26, and I understand the date fields better now.

I'll add detail to the IS.

IMO it also needs before / after screenshots of radios, checkboxes, and the different date/time field types. I will add these.

I think a followup is required for timestamp fields. My sense is that they should actually be in a fieldset because they consist of two related fields.

kentr’s picture

Issue summary: View changes
Issue tags: -Needs tests, -Needs issue summary update
  1. Regarding #107, the MR had changes to summary elements, but they had not been done in Claro or Olivero yet. Now they are.
  2. I added tests for legend and summary.
    The others I saw in the MR, in \Drupal\Tests\system\Functional\Form\ElementTest::testRequiredFieldsetsAndDetails(), only apply to the starterkit_theme. It looks like applying that test file to starterkit_theme was intentional for #3304731: Update remaining tests using Classy to use Starterkit , so I left it as-is.
  3. I added tests for datetime-wrapper.html.twig.
  4. I updated the Admin theme templates.
kentr’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs screenshots
StatusFileSize
new305.17 KB
new275.24 KB
new304.66 KB

Forgot to mention that I also added test coverage for datetime-wrapper.html.twig.

Attaching before / after screenshots with more fields in Claro, Olivero, Admin theme. As these are for visual regression checks, not to demonstrate the changes, the left & right sides of each should be identical.

[edited for clarification]

kentr’s picture

Issue summary: View changes
rkoller’s picture

StatusFileSize
new200.83 KB
new456.19 KB
new221.77 KB
new463.88 KB
new270.06 KB
new501.73 KB
new49.27 KB
new46.2 KB

created again another content type containing every available field in core and created with and without css screenshots on the node edit form with claro, admin, and olivero, plus the same for the login page.

over all this looks good to me from a manual testing perspective, excellent work @kentr thank you! the only detail i consider odd are the stars on the fieldsets and then on the fields within that fieldset again - potential scenarios, sometimes a single field, sometimes several, sometimes every field within. but that is something that could be solved within #3174459: [PP-1] W3C Validation: required attribute not allowed on fieldset tag . that is out of scope for this issue imho.

rkoller’s picture

Issue summary: View changes

added some context to the before and after screenshots section in the issue summary

kentr’s picture

@rkoller

over all this looks good to me from a manual testing perspective, excellent work @kentr thank you! the only detail i consider odd are the stars on the fieldsets and then on the fields within that fieldset again - potential scenarios, sometimes a single field, sometimes several, sometimes every field within. but that is something that could be solved within #3174459: [PP-1] W3C Validation: required attribute not allowed on fieldset tag . that is out of scope for this issue imho.

In your opinion, can we mark it as RTBC after the draft change record is added?

kentr’s picture

Status: Needs review » Needs work

Still needs a change record.

If anyone thinks that's doable by a novice, please add the Novice tag.

kentr’s picture

Issue summary: View changes

I'm working on a change record.

I also want to confirm that all of #62 has been addressed. In particular, I'm not certain that point 5 was addressed.

kentr’s picture

Issue summary: View changes
Issue tags: +Needs tests

Think it needs some additional assertions for JavaScript states.

kentr’s picture

Added STR for cases using the JavaScript states API.

There are cases where the space is missing between the "(required)" text and the main part of the accessible name. Here's a screenshot showing that.

kentr’s picture

Issue summary: View changes

Added a draft CR. It needs some work.

kentr’s picture

kentr’s picture

Issue summary: View changes
Issue tags: -Needs change record updates

Updated the CR with before / after examples for template modifications.

kentr’s picture

Working on the other code and test changes.

kentr’s picture

Issue summary: View changes
Issue tags: -Needs tests +Needs manual testing

Addressed the code items in Remaining tasks.

I think it needs additional manual testing just for the JavaScript states API. See the Steps to reproduce for details.

kentr’s picture

Status: Needs work » Needs review

I just pushed the update that I meant to push before my last comment...

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

kentr’s picture

I'll rebase it.

kentr’s picture

Status: Needs work » Needs review

Rebased and passing.

mherchel’s picture

Just a drive by here (sorry!).

I haven't read through the full thread, but I did look at the MR.

There may be an easier way to do this. We could do something like this with CSS only:

.form-item::after {
  /* Element content and "required" are read out */
  content: "*" / "required";
}

See https://www.stefanjudis.com/today-i-learned/css-content-accepts-alternat...

mherchel’s picture

...but it wouldn't be translatable (unless we add it via JS)

kentr’s picture

@mherchel

There may be an easier way to do this. We could do something like this with CSS only:

Thanks for looking!

Were you saying to use CSS only instead of adding actual text in the markup?

If so... One of main goals is to have the textual "required" present in cases where CSS is disabled. That's what the "not use full CSS" refers to...

kentr’s picture

Issue summary: View changes
mherchel’s picture

TBH, I think my idea is dead in the water because of lack of translation. If we went with JS, it would add a lot of complexity.

kentr’s picture

Title: Drupal should not use full CSS required marker in forms according to WCAG 2.0 » Drupal should not use CSS-only required marker in forms according to WCAG 2.0
Issue summary: View changes
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

kentr’s picture

I'll rebase it.

kentr’s picture

Status: Needs work » Needs review

Rebased and passing.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

rkoller’s picture

Looks like the tests still pass? I've checked out MR12981 and went through a node edit form containing all available field types in core another time. Tested that node edit form with Claro, Default Admin, and Olivero - all looked good to go. The output of the required label on fieldsets will be covered in #3174459: [PP-1] W3C Validation: required attribute not allowed on fieldset tag . A Change Record that looks good and complete is available at https://www.drupal.org/node/3580406 and the issue summary is also in a good shape in general. Not sure why the need review bot reverted the issue back to needs work? From my perspective in case there isnt anything ive missed in regard to failing tests, this issue looks good to go and ready for RTBC?

kentr’s picture

I'll rebase it.

duaelfr’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs framework manager review, -Needs manual testing

Everything still looks good.
Tests are green, code has been reviewed multiple times, manual reviews has been done extensively and a change record has been written.
Let's go!

kentr’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs manual testing

I believe it still needs manual testing for the JavaScript states case (#130).

kentr’s picture

^^ See the Steps to reproduce for details.

rkoller’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new97.87 KB

Good point, thanks for the reminder, missed that detail. I've quickly tested for Javascript States pointed to in #148... Works in latest Safari, Firefox Developer Edition, and Edge:

node edit for in the form test module with css disabled in safari

The rest still looks good to go as well. Setting back to RTBC

kentr’s picture

Issue summary: View changes
Issue tags: -Needs manual testing
kentr’s picture

Issue tags: +a11y-bugsmash

Added a11y-bugsmash tag.

quietone’s picture

Title: Drupal should not use CSS-only required marker in forms according to WCAG 2.0 » Do not use a CSS-only required marker in forms per WCAG 2.0

Removing the 'Drupal should' from the title because that is redundant since this is the Drupal core queue.
The change record clearly shows what developers/themers should for the templates changes, which is great to see. I moved some text around at the beginning to put the change first, which is the preferred style.

I updated credit.

kentr’s picture

I don't mean to rock the boat, but now that I've seen a mechanism for appending text to labels / names without modifying templates, I'm wondering if that's a better approach.

Adding the '(required)' text in templates means that existing sites with custom templates have to update their templates, and also carries the risk that it will get accidentally removed from custom templates during their lifespan.

As an alternative, it may be possible to add the text in a ::preRender(), similar to how it is done for #2848507: Indicate that grouping elements have child element errors for ux and a11y:

$element['#title'] = new TranslatableMarkup('@title <span class="visually-hidden child-error-indicator">(contains error)</span>', ['@title' => $element['#title']]);

I also wonder if translating the full string like this instead of just the '(required)' text by itself yields a better translation result for some languages.

I'm curious to hear others' opinions.

catch’s picture

Status: Reviewed & tested by the community » Needs review

I think it's worth exploring #154, if we can handle it centrally that will save updating a lot of templates, work for contrib, and agreed it's likely to be a lot better for translation. I also think appending (required) won't necessarily work for RTL languages - was that tested?

rkoller’s picture

StatusFileSize
new258.17 KB

uhhh damn, good point about RTL, at least i had forgot testing that as well. i have caught up on that oversight of mine and just tested with the current state of the MR. just switched to hebrew and the (Required) tag is to the right of for example the username label, that should be on the left instead

the user profile page for rkoller without css and with reading direction right to left in hebrew but due to the lack of translation entirely in english

smustgrave’s picture

Status: Needs review » Needs work

Kentr asked about this on the side and agree with a non template approach.

kentr’s picture

I'll work on the changes.

I tested before with a Hebrew translation file imported manually via the languages UI, and again just now with the current MR.

The text "(required)" is to the left of the Hebrew, between the input and the Hebrew.

Here's a screenshot of the user edit page with Hebrew set as the default language. It should be the same fields as in @rkoller's screenshot, I think, but a Hebrew reader would have to confirm.

I can't say why English in RTL doesn't work this way in @rkoller's screenshot. It might have something to do with the difference between a language and a script. My understanding is that languages aren't RTL, but rather it's the script that is RTL.

Screenshot of the user edit form in Hebrew, with the '(required)' text highlighted by a dashed red oval

kentr’s picture

Status: Needs work » Needs review
StatusFileSize
new35.67 KB

The MR with the new strategy is for review. I'm hiding the other MR for now.

I think it would be best to get approval on the general code strategy before more manual testing:

  1. Add a #pre_render callback method to FormElementBase.
    This method appends "(required)" to #title when the criteria are met.
    Use a #pre_render callback because AFAICT it must be done after validation so that the unmodified #title is used for validation error messages.
  2. With all render elements for HTML form inputs, automatically add this callback to the list of the element's callbacks in FormBuilder::handleInputElement().
    These are elements which for which $element['#input'] is TRUE.
  3. With non-input render elements such as Details and Fieldset, add the new #pre_render callback explicitly in the element's ::getInfo() method.

Other notes

  • There's a standalone Label render element, and I added code for it to work. I think it was previously working because it uses the same template as automatic labels.
  • In states.js, I changed the logic a little to use a data-drupal-required attribute on the span instead of the CSS class js-required.
    This is because I wanted to make the PHP and JavaScript versions the same in order to have only one version of the string for translation, and it seems inappropriate to add js-required to an element in PHP.
    It also seems less likely that someone will remove the data-drupal-required attribute than a js-required class.
  • I did a rough pass to test translation.
    The string shows up in the translation interface as @title <span aria-hidden="true" class="hidden" data-drupal-required> (required)</span>, which sounds like what we want based on the translation documentation.
    Here's screenshot of the login form with a translation entered for Hebrew (CSS is disabled).
  • I rebased both MRs to make comparing them easier and also attached an interdiff between the them.

[edit: added a link to relevant code in the MR]

kentr changed the visibility of the branch 2921627-required-fields-a11y to hidden.

kentr’s picture

Tagging for subsystem maintainer review to get feedback on the strategy in #160.

Also uploading the image again. It doesn't appear to have saved.

kentr’s picture

Issue summary: View changes
smustgrave’s picture

not a forms maintainer but like this approach a lot better then before!

larowlan’s picture

Left a comment on the option 1 MR as to why I personally prefer that one.

kentr’s picture

Issue summary: View changes

@larowlan, thanks for the review and the comments on the MR. I replied in the MR regarding the drawbacks that I see on Option 1.

Also WRT drawbacks, @catch said this about a non-template approach in #155:

I think it's worth exploring #154, if we can handle it centrally that will save updating a lot of templates, work for contrib, and agreed it's likely to be a lot better for translation. I also think appending (required) won't necessarily work for RTL languages - was that tested?

Not sure what's next for this.

It looks like @larowlan didn't have any concerns about the code in the MR for Option 2.

Option 1 would be RTBC except for #156. However, in my testing (#158) the new text was to the left of the main label as expected. I don't know if that satisfies #156 and qualifies for RTBC.

I rebased the MR for Option 1 (https://git.drupalcode.org/project/drupal/-/merge_requests/12981).

I suspect further manual testing should wait until it's clear which approach we're taking.

kentr changed the visibility of the branch 2921627-required-fields-a11y to active.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

kentr’s picture

I'll rebase it.

kentr’s picture

Status: Needs work » Needs review

Rebased and passing.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new3.35 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

duaelfr’s picture

Status: Needs work » Needs review

Rebased on main

larowlan’s picture

larowlan’s picture

Issue tags: +Needs release note

Discussed in slack @rikki_iki said:

I think I'd lean towards php, twig feels the natural place but the idea of there being no marker feels worse than some having two. ie two is more obvious and likely to get fixed, none could go unnoticed for some time

She makes an excellent point about it being noticeable - so I've changed my mind - let's press ahead with the PHP approach and just note the change in a release note for themers.

Rikki also pointed out we'd need to be able to customise the class.

larowlan changed the visibility of the branch 2921627-required-fields-a11y-reduce-template-changes to hidden.

larowlan changed the visibility of the branch 2921627-required-fields-a11y-reduce-template-changes to active.

larowlan changed the visibility of the branch 2921627-required-fields-a11y to hidden.

larowlan’s picture

Status: Needs review » Needs work

Left a comment about making the required marker markup overidable by a theme per comment from @rikki_iki

kentr’s picture

Issue summary: View changes

Thanks @larowlan.

The MR was pretty behind, so I rebased it.

kentr’s picture

Status: Needs work » Needs review

I made it themeable.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

kentr’s picture

Assigned: Unassigned » kentr

Will rebase

kentr’s picture

Assigned: kentr » Unassigned
Issue summary: View changes
Status: Needs work » Needs review

Rebased.

rkoller’s picture

StatusFileSize
new36.12 KB

An early observation, the override stuff i still have to figure out how to manually test first. but to me it looks like (required) replacing the star does not work for the media field in the latest state of the MR. identical results in safari and edge.

the reference, media, and file field without css available

kentr’s picture

Assigned: Unassigned » kentr
Status: Needs review » Needs work
Issue tags: +Needs change record updates

@rkoller found that the change record still reflects Option 1 and that the new " (required)" text doesn't appear for media fields.

kentr’s picture

Assigned: kentr » Unassigned
Status: Needs work » Active

Back to Needs review.

I also checked some other field types that are coded as a "Widget". The media entity reference field seems to be an outlier.

kentr’s picture

Assigned: Unassigned » kentr
Status: Active » Needs work

There's another problem.