Child elements in grouping elements like (meta) details and vertical tabs are invisible to the user when the grouping element is closed or not-focused respectively.
To improve the user experience and accessibility we should indicate when there are errors 'inside'.
Currently it is hard for the user to find the actual problematic field when the (child) field itself is invisible.

Note that only the Seven theme knows the additional concept of using Details elements as meta data elements at the right side of the node edit page.


Meta details open (Seven only, LTR)
details before

After (proposal)

Meta details open (Seven only, LTR)

Meta Details closed (Seven only, LTR)

Meta details open (Seven only, RTL)

Meta Details closed (Seven only, RTL)

Normal Details closed (Seven only, LTR)

Normal Details closed (Bartik, LTR)

Vertical Tabs not focused (Seven, LTR)

Vertical Tabs not focused (Seven, RTL)

Vertical Tabs focused (Seven, LTR)

Vertical Tabs non focused (Bartik, LTR)

#66 2848507-64-grouping_element_child_errors.PATCH_ONLY.patch5.51 KBdmsmidt
#64 2848507-64-grouping_element_child_errors.patch17.03 KBdmsmidt
#64 interdiff-2848507-62-64.txt1.07 KBdmsmidt
#54 interdiff-2848507-48-54.txt13.21 KBdmsmidt
#54 2848507-54-grouping_element_child_errors.patch11 KBdmsmidt
#50 details_bartik_child_errors.png20.82 KBdmsmidt
#50 details_bartik_child_errors_before.png21.45 KBdmsmidt
#48 interdiff-43-48.txt1004 bytesBarisW
#48 2848507-48-grouping_element_child_errors.patch8.76 KBBarisW
#47 jira-error.png11.84 KByoroy
#43 2848507-43-grouping_element_child_errors.patch8.17 KBpk188
#38 2848507-38-grouping_element_child_errors.patch7.35 KBpk188
#34 2848507-34-grouping_element_child_errors.patch7.17 KBdmsmidt
#34 interdiff-2848507-32-34.txt1.18 KBdmsmidt
#32 interdiff-2848507-17-32.txt4.55 KBdmsmidt
#32 2848507-32-grouping_element_child_errors.patch5.75 KBdmsmidt
#32 details_child_errors_closed_ltr_bartik.png2.83 KBdmsmidt
#32 vert_tabs_child_errors_non_focus_ltr_bartik.png12.18 KBdmsmidt
#32 details_child_errors_closed_ltr_seven.png2.86 KBdmsmidt
#32 meta_details_child_errors_closed_ltr_seven.png7.59 KBdmsmidt
#32 meta_details_child_errors_open_rtl_seven.png29.4 KBdmsmidt
#32 meta_details_child_errors_closed_rtl_seven.png11.52 KBdmsmidt
#32 vert_tabs_child_errors_focus_ltr_seven.png51.02 KBdmsmidt
#32 vert_tabs_child_errors_non_focus_ltr_seven.png47.06 KBdmsmidt
#32 vert_tabs_child_errors_non_focus_rtl_seven.png47.91 KBdmsmidt
#25 details-error-mark.png45.98 KByoroy
#24 error_message_drupal_styling.png1.97 KBdmsmidt
#17 drupal-n2848507-17-without.png21.44 KBDamienMcKenna


dmsmidt created an issue. See original summary.

dmsmidt’s picture

We just talked about this in the UX hangout discussion (
At least we can color the borders red and make them a bit thicker.

Since #2754977: Enhance formErrorHandler to include children errors on RenderElements is in we now have enough information on the grouping elements to know if there are errors on child elements.

andrewmacpherson’s picture

Issue tags: -a11y

Tag clean up: "accessibility" is the preferred one. The "a11y" tag doesn't have many issues so I'm moving them all to "accessibility".

andrewmacpherson’s picture

For vertical tabs we could iappend an error indication in the tab summary message.

e.g. if there is one error, say "Error: [field label]", or if there are several errors, something like "Contains multiple errors."

It doesn't help us with the details group though.

dmsmidt’s picture

@adrewmacpherson, do we really need to add text?
What about adding the IFE error icon before the labels and adding a thick red border?

dmsmidt’s picture

Assigned: Unassigned » dmsmidt

Working on the PHP part.

dmsmidt’s picture

Assigned: dmsmidt » Unassigned
Status: Active » Needs review
Issue tags: +Needs tests

Here is a first stab at things. This will add the 'error' class to tabs with errors.
And the 'error' class plus 'aria-invalid' to details and fieldsets.
Stylers go ahead!

We will need a functional JS test for this.

dmsmidt’s picture

Also, added vertical tabs to the module for easy testing:

dmsmidt’s picture

Status: Needs review » Needs work

The last submitted patch, 9: 2848507-9-grouping_element_children_errors.patch, failed testing.

andrewmacpherson’s picture

@dmsmidt Re: comment #5

Yes, an error icon (with fallback text) will do the job, better than my text suggestion.

I was trying to address "At least we can color the borders red and make them a bit thicker" from comment #2. A thick red border alone would not be sufficient to convey an error because:

  • Red is not sufficient because (1) users with colour-vision impairments can have difficulty perceiving it, and (2) it may not work effectively in other colour spaces (e.g. Windows' high contrast mode). In other words, can a user distinguish between a tab with a red border, and a tab with a dark-grey border?
  • A thick border has no meaning, and can convey anything. It's sometimes used to convey :focus, for instance.

Including the error icon in vertical tabs addresses these, because it uses shape as well as colour, and is a meaningful indication of "error".

andrewmacpherson’s picture

Review of the patch in #9:

  1. In vertical tabs, the class="error" and aria-invalid="true" attributes are applied to the the <details> element nested inside the tab panel (via PHP) and the error class is applied to the vertical tab itself via JS. I changed the names of these classes to confirm it worked.
  2. Adding an error class will not be sufficient on it's own. Presumably the idea is that this class would be used to add an error icon (a red cross, say). If it's just an icon, it will need a text fallback. Ideally this would be an inline image element, but we don't seem to use many of those in core anymore. A CSS background images and/or generated content will not be presented to screen readers, so we should either use an inline image element with an alt attribute, or include a span.visually-hidden the vertical tab somehow, such as a translatable string in vertical-tabs.js. (I would put it after the tab title, but before any vertical tab summary text. This might mean prepending it to the tab summary string.)
  3. I don't think it is an appropriate use of aria-invalid to put it on the container element. The WAI-ARIA recs (1.0 or 1.1CR) are a bit vague on this, saying it can be used on "all elements of the base markup". As far as I am aware though, it is only supported when it is applied to a form input element, not a div/details wrapper. In a quick test with Chromevox and the errorstyle module, it was not announced.
ttamniwdoog’s picture

43.83 KB
153.89 KB
449.13 KB

Steps to recreate:
1) In Drupal 8.4, create a new article content type here: /node/add/article
2) Scroll down to the URL Path Settings in the vertical tabs: /node/add/article#edit-path-settings
3) Enter in a node title and then enter in a bogus URL that doesn't start with a forward slash("/") as seen here:
4) Click "Save and Publish"
5) After saving the page, you should see an error at the top of the page like:
6) Also notice the error seen in the URL Path Settings now. Should look like this:

markie’s picture

As part of an internal accessibility sprint we determined these next steps:

  1. Identify attributes to be added to which element (summary / details)
    1. Reuse error class on both.
  2. Add class programmatically
    (/core/misc/vertical-tabs.js (line 68ish)
  3. Submit patch for HTML changes.
  4. Update CSS to properly show changes.
  5. Submit patch for CSS changes.
  6. Identify correct ARIA attribute(s) to add.
    1. Add “aria-invalid = true”?
    2. Do any other CMSes try to solve this issue?
    3. Are there any articles that discuss this issue?
    4. No ARIA is better than bad ARIA
  7. Update tests to confirm changes.
  8. Submit patch with test changes.
  9. (repeat steps 6 and 7 as needed)
andrewmacpherson’s picture

Re: #14 - I think we've covered all of that in the various comments so far.

Identify attributes to be added to which element (summary / details)

Reuse error class on both.

Do you mean adding a .error class to the details and the summary elements? Surely we can style the summary with a selector like details.error summary.

aria-invalid=true doesn't work for anything other than form inputs, so putting it on a <details> is of no benefit.

dmsmidt’s picture

I think it is pretty clear where we stand.

As per #12-2 we now need to "visually" show that there is a child error, some solution are proposed.

@andres (#12-3), I did some research about aria-invalid before I made the patch, but indeed those specs are very vague. I read them as: 'it is ok to add them to elements other than things like , but we may not do anything with it". I'm ok with removing them.

DamienMcKenna’s picture

Here's what a motley crew at Mediacurrent came up with (cehfisher, DamienMcKenna, dbungard, markie, Michelle, samuel.seide, smurrayatwork, ttamniwdoog, Widescreen_bob). This adds a border to the fieldset ("details" tag) in both expanded and collapsed formats, and then adds the error check mark to the summary text.

This is what the error message looks like without the changes:

Without any changes.

This is what the error message looks like with the changes:

With the patch applied.

While reviewing this it was noticed that the field with the error class is not AAA compliant (red text with a reddish background color), maybe something to look at later?

dmsmidt’s picture

First actual visual changes, great!

Indeed, the field error styling should have it's own issue.

Could you also provide a screenshot of how this looks on closed details? The most pressing concern is that it is not clear where errors are if a details is closed or a vertical tab not focussed.

How would the proposal translate to vertical tabs, could you guys come up with something similar?

One thing I thought when looking at the icon in the top right: 'this looks like a red close button'. Although it is perfectly aligned, the location may not be the best. Any thought?

DamienMcKenna’s picture

This is what the fieldset looks like when it's collapsed:

With the patch, when the fieldset is collapsed.

DamienMcKenna’s picture

We did not get into vertical tabs in the main content area, we just focused on the sidebar fieldset on node forms.

dmsmidt’s picture

Great start. Thanks for the additional screenshot.

In closed form the red icon works better. Maybe we can remove it when the element is open. In combination with IFE the icon would already be present beneath the field.
Maybe a screenshot with IFE enabled and the element open would also help.

One, not belittling ment note: in D8 fieldsets can't be collapsed anymore, they are sort of replaced by details elements. Let's keep the terminology clear to avoid confusion.

Status: Needs review » Needs work

The last submitted patch, 17: drupal-n2848507-17.patch, failed testing.

dmsmidt’s picture

Issue summary: View changes
dmsmidt’s picture

1.97 KB

Design feedback / idea from the UX meeting of 15 march (see demo at:

"Reuse the error message styling (thick left border)."
"In open state and IFE enabled the element becomes crowded."

yoroy’s picture

Issue tags: -ux, -user experience +Usability
45.98 KB

An incomplete proposal:

- How it could look with the red left border (using the wrong color red here)
- Can we do something with a ::before pseudo CSS class to add actual error wording to the container?

andrewmacpherson’s picture

Re: #25

The thick red border looks smart! I expect it will work just as well inside a vertical tab header.

Using a thick border alone (comment settings in the screenshot) isn't enough IMO. The fact that it's thicker than the regular border technically means it doesn't rely on colour alone. However the thickness doesn't convey "error" - the red colour provides that. Including the error icon would be better because it's a meaningful symbol.

So far the screenshots have used the special details styling from Seven's node form. We'll need to make it work with Seven's general details style, and Bartik.

- Can we do something with a ::before pseudo CSS class to add actual error wording to the container?

No, CSS-generated text presents a few problems:

  • Currently, not all browsers pass the CSS content to host accessibility APIs. Accessible Name and Description: Computation and API Mappings 1.1 will eventually require user agents to take CSS content into account - it's still at the working draft stage. Some browsers already support it, but notably IE11 does not. I don't expect this will ever be fixed in IE, so until we drop support for IE11 we should avoid including text via CSS.
    EDIT: I tried a CSS generated content test case with Chrome 57 + ChromeVox. This combination doesn't read the CSS generated content either.
  • The wording needs to be translatable. So far we've only used CSS content: for a few punctuation symbols, not translatable strings. It's possible to use HTML attributes to provide CSS content (e.g. content: attr(data-foo); but I don't see how that's better than just putting it in a HTML element.

The patch in #17 adds the error class to vertical tabs via JS. We can provide a translatable string at the same time. For details elements, providing error wording in HTML would be preferable I think.

andrewmacpherson’s picture

Patch from #17:

+.entity-meta details.error,
+.entity-meta details[open].error {

The entity-meta sidebar markup comes from Seven. These selectors belong in core/themes/seven/css/components/entity-meta.css.

andrewmacpherson’s picture

Re: #17

While reviewing this it was noticed that the field with the error class is not AAA compliant (red text with a reddish background color), maybe something to look at later?

It has a contrast ratio of 7.02:1 which does indeed pass at level-AAA. In any case our target for the core a11y gate is 4.5:1 to meet level-AA.

I just reviewed the information at Specifying colors and contrast for accessibility - it's a bit misleading because it says we need to meet level-AA, but then mentions the enhanced contrast ratios needed for level-AAA. I should update that page to make it clearer which numbers are for level-AA. Although obviously I'd prefer we met AAA, which we do :-)

dmsmidt’s picture

Issue tags: +DevDaysSeville
yoroy’s picture

Forgot to say thank you to @andrewmacpherson for explaining why and how. Thank you @andrewmacpherson :)

dmsmidt’s picture

Assigned: Unassigned » dmsmidt

Working on this @Seville.

dmsmidt’s picture

  • Added error styling for vertical tabs.
  • Added the thick border to the left (with a bit of a rounded corner), corresponding to the error message styling.
  • Styling done per component (separate css files).
  • Position the icon correctly on multi-line titles/summaries.
  • Added the error styling also to Stable to have it show in Bartik. Since this is a bugfix and the styling is on a new class I think we can add this styling to Stable.
  • Also made the details element (with child error) background for Bartik white to have enough contrast.
  • The error styling is disabled when a fieldset is focused or a details element is open, this prevents that the UI becomes too crowded. When the children are shown, we don't need to mark the grouping element anymore.
  • Added RTL styling.

Some after screenshots added to the descriptions according to these changes.

- Novice: add before screenshots of all after scenarios
- Fix test fail
- Provide error wording for a11y
- Tests (check for the error class and error wording)

Status: Needs review » Needs work

The last submitted patch, 32: 2848507-32-grouping_element_child_errors.patch, failed testing.

dmsmidt’s picture

This adds some missing CSS and fixes the test failure.
We now cover the addition of the error class for details elements in our tests.
Concerning the tests, we now only need a Functional JS test for the error class on Vertical Tabs.

lauriii’s picture

Status: Needs review » Needs work

We should not make any changes to Classy or Stable on this issue because they are frozen. We only want to change them on bug fixes that are non-disruptive and major enough. The first assumption should always be that we cannot change them. However, what we can do is create minimalistic styles for core and a bit nicer styles for Bartik and Seven. Then in Drupal 9 those styles will be available in Stable.

+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -204,6 +204,11 @@ public static function preRenderGroup($element) {
+      $element['#attributes']['class'][] = 'error';

We should use data attribute instead of classes when the selector is used by JavaScript

andrewmacpherson’s picture

Re: #35 - I think this error class will be relevant without JS. Currently we use a polyfill-type of approach for the details/summary elements, but native support is now in Blink and Firefox. Details/summary groups work in these browsers when JS is disabled - this class is used for styling in the patch, combined with the native HTML5 'open' attribute...

+details.error:not([open]) {
wolffereast’s picture

pk188’s picture

Status: Needs work » Needs review
7.35 KB

Re-rolled and fixed #35

Status: Needs review » Needs work

The last submitted patch, 38: 2848507-38-grouping_element_child_errors.patch, failed testing.

andrewmacpherson’s picture

This needs a re-roll to account for Drupal core now using ES6 for javascript development. That change record describes the new contributor workflow for ES6 javascript. See the sections on "creating (or reviewing) core patches".

The patch in #38 changes core/misc/vertical-tabs.js, but the new ES6 file core/misc/vertical-tabs.es6.js needs to be updated too.

andrewmacpherson’s picture

Issue tags: +Needs reroll
andrewmacpherson’s picture

Issue tags: +sprint
pk188’s picture

pk188’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

Status: Needs review » Needs work

The last submitted patch, 43: 2848507-43-grouping_element_child_errors.patch, failed testing. View results

BarisW’s picture

Assigned: Unassigned » BarisW

I'll work on this patch as part of the Haarlem accessibility sprint.

yoroy’s picture

11.84 KB

Jira puts the icon inside the thick left border, maybe we can do same?

BarisW’s picture

Assigned: BarisW » Unassigned
Status: Needs work » Needs review
8.76 KB
1004 bytes

Fixed the error introduced in #43. I would suggest adding these changes to classy, I think this is the most minimal version that needs to be added to Classy.

andrewmacpherson’s picture

@yoroy - that Jira style is interesting. If we put the icon inside a thick border for this issue, would we want to change our message boxes to match?

dmsmidt’s picture

Status: Needs review » Needs work
21.45 KB
20.82 KB

@andrewmacpherson and @yoroy, thanks for the nice styling idea. I think it could be implemented in a new theme. The styling introduced by this patch are in line with current styling patterns of errors and proposed during an UX meeting (see #24). Redesigning (error) messages is out of scope for this issue.

@lauriii these styling addition (no changes) are actually major accessibility bug fixes. And as mentioned in #36 the class is used for styling. Could you reconsider?

Bartik details element styling is off, see:


yoroy’s picture

I was trying to address #26, the part where a thick border only was not considered enough. But the current error icon is already added here as well so that's ok then. Agreed that a new design is out of scope here.

lauriii’s picture

  1. +++ b/core/misc/vertical-tabs.es6.js
    @@ -60,7 +60,8 @@
    +            children_errors: $that.hasClass('error')
    +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
    @@ -197,13 +197,18 @@ public static function preRenderGroup($element) {
    +      $element['#attributes']['class'][] = 'error';

    Could we add a JS specific indicator for the errors? Also, .error isn't the most self-documenting name for this.

    Also according to Classy's BC policy, this change isn't allowed. However, I think if we can make this more specific we could make this change since it wouldn't cause too much of risk anymore and would still be a great improvement.

  2. +++ b/core/misc/vertical-tabs.es6.js
    @@ -246,6 +247,11 @@
    +      tab.item.addClass('error');

    Could we use the BEM modifier pattern for naming the class for the visual styles?

  3. +++ b/core/themes/classy/css/components/details.css
    @@ -21,3 +21,30 @@ summary {
    +details.error:not([open]) summary:before {

    Changes to Classy aren't technically allowed. We should move these changes to Seven.

  4. +++ b/core/themes/seven/css/components/entity-meta.css
    @@ -57,3 +57,21 @@
    +.entity-meta details.error:not([open]) {

    If we can come up with a more specific class name, we could probably make the CSS less specific.

dmsmidt’s picture

Assigned: Unassigned » dmsmidt
dmsmidt’s picture

Assigned: dmsmidt » Unassigned
Status: Needs work » Needs review
Issue tags: -Novice
11 KB
13.21 KB

I addressed all @laurii's concerns in this patch, only styling for Bartik and Seven are changed. I also fixed #50 (Bartik details styling regression).

I'll create a follow up issue to make this even more accessible by announcing the amount of child errors if a closed detail/tab gets focus.
This is however a bit out of scope, but the groundwork is now also present (data-child-errors-count).

Should we mark this Major priority btw? Since it is a blocker for Inline Form Errors and a serious non-contained accessibility bug.

Edit: created follow up and working on a fix #2892443: Announce that grouping elements have child element errors for accessibility.

Status: Needs review » Needs work

The last submitted patch, 54: 2848507-54-grouping_element_child_errors.patch, failed testing. View results

andrewmacpherson’s picture

Status: Needs work » Needs review
11.04 KB

This needed a re-roll following #2880007: Auto-fix ESLint errors and warnings. There was trouble with some offsets, and the first chunk in vertical-tabs.es6.js already had a trailing comma after the ESLint changes in that issue.

-            details: $that
+            details: $that,
+            children_errors: $'children-errors-count')

Sorry, no interdiff file. I got errors when trying to make one, relating to the same chunk. I manually compared patches #54 and #56 prior to uploading it here.

andrewmacpherson’s picture

The simplest way to announce that grouping elements have child errors in a screen reader, is for the error icon to have alternative text (see comment #11).

However, the icon is a CSS background image, on a pseudo-element, so we can't associate the text-alternative directly with the icon :-(

The workaround for this is to provide the text alternative in a span.visually-hidden, nested inside the focusable control, so it forms part of the computed accessible name.


<details open data-drupal-selector="edit-nested-details-closed" id="edit-nested-details-closed" class="js-form-wrapper form-wrapper form-wrapper--child-error details--child-error" data-children-errors-count="1">
  <summary role="button" aria-controls="edit-nested-details-closed" aria-expanded="false" aria-pressed="false">
    :: before
    Nested details closed
    <span class="visually-hidden child-error-indicator">(contains error)</span>



The interesting part is that the icon disappears when the grouping element becomes open. Do we make the text fallback disappear too? I can imagine a confusing scenario like this...

  • A user finds a grouping element and hear "contains errors"
  • They open the grouping element, then go off browsing the rest off the page, e.g. by navigating headings
  • Try to come back to the error, and not be able to find the grouping element that "contains errors".

So let's leave the text-alternative in place (visually-hidden) all the time.

I'd rather deal with the text-alternative in this issue, instead of a follow-up. I might take a crack at it tomorrow.

dmsmidt’s picture

Status: Needs review » Needs work

Some valid points by @andrew, so putting this back to needs work.

dmsmidt’s picture

Assigned: Unassigned » dmsmidt
dmsmidt’s picture

Assigned: dmsmidt » Unassigned
Status: Needs work » Needs review

Here is an implementation of what @andrew suggested.
Could you test it?

If it works we should add a functional JS test for the vertical tabs en elaborate on the existing browsertest a bit.

dmsmidt’s picture

dmsmidt’s picture

Woop, first Functional JS test for a core Render element (hooray for a11y tests) :-).
We now have full test coverage for details and vertical tabs concerning the changes of this issue.
I also did some further cleaned of the patch.

For the JS reviewers, note that we now need to use html() instead of text() to support the hidden error indicator span.

Status: Needs review » Needs work

The last submitted patch, 62: 2848507-62-grouping_element_child_errors.patch, failed testing. View results

dmsmidt’s picture

Test fix.

drpal’s picture


Can you upload a test only patch for #64?

dmsmidt’s picture

Sure, here it is.

Also bumping the priority, cause it is a IFE blocker and also without IFE an accessibility problem.

Status: Needs review » Needs work
dmsmidt’s picture

Status: Needs work » Needs review

Fails as expected.

drpal’s picture

  1. +++ b/core/misc/vertical-tabs.es6.js
    @@ -56,8 +56,9 @@
    +            title: $that.find('> summary').html(),

    The expected behavior here is that the html contents is returned instead of a glob of all the text nodes?

  2. +++ b/core/misc/vertical-tabs.es6.js
    @@ -56,8 +56,9 @@
    +            child_error_count: $'child-error-count'),

    This isn't critical, but it is something to think about. The way jQuery is storing data attributes is changing in 3.0,

dmsmidt’s picture


#69.1: yes it is, see #62, last sentence.
#69.2: alright, I'll keep that in mind. I guess there will be a major cleanup when the time comes for Drupal.

yoroy’s picture

andrewmacpherson’s picture

Manual testing of patch #64. I used the dmsmidt/errorstyle test module, and node/article/add.

I like it very much :-) I'm happy to sign off on this approach for the icon's text alternative.

A couple of points about the message text in formatPlural():

  1. + '@title <span class="visually-hidden child-error-indicator">(contains an error)</span>',
    Let's shorten this to "contains error". Most native screen reader announcements are quite terse (in English at least) and little words like "an" sound out of place.
  2. + '@title <span class="visually-hidden child-error-indicator">(contains @count errors)</span>
    Mixed feelings about this. When a group is closed the error icon doesn't convey the number of child errors, so we're giving a screen reader user information that we're not providing to sighted users. However when a group is open, it's very easy for a sighted user to see that it "contains 3 errors". Overall, I think we can leave this as it is - it will very likely help a user orient themselves when reviewing vertical tab titles.