Skip to content

ItemGroup can be misused and render unsemantic not accessible markup #67425

Description

@afercia

Description

<ItemGroup> is supposed to 'display a list of Items grouped and styled together.

The items are supposed to be visually and semantically grouped because the <ItemGroup> renders a div element with an ARIA role=list. This is basically equivalent to an <ul> element. As such, it is supposed to only contain <Item> sub-components that render a div element with role=listitem. This is basically equivalent to <li> elements.

As such, <ItemGroup> is the ARIA equivalent of an unordered list with list items.

The documentation clearly states that ItemGroup should be used in combination with the Item sub-component. The documentation example is pretty clear as well.

However, in practice, ItemGroup accepts any children. There are several examples in the codebase where children other than <Item> are used within an <ItemGroup>. This is semantically incorrect and not accessible. It's basically the equivalent of an <ul> element that contains elements other than <li> elements.

Unfortunately, contributors to this project seem to not read the documentation and misuse this component only to get the 'visual aspect' of the <ItemGroup> not realizing they're going to render unsemantic and not accessible markup.

On the other hand, the <ItemGroup> component doesn't enforce its children to be <Item> sub-components. I would argue that it should, given its intended usage and its documentation.

One example of this misuse is in the block bindings UI:

Image

<ItemGroup>
<Text variant="muted">
{ __(
'Attributes connected to custom fields or other dynamic data.'
) }
</Text>
</ItemGroup>

where the text highlighted in the screenshot is a <span> element inside a <div> element with role=list. The equivalent in HTML would be something like the following:

<ul>
    <span>Some text</span>
</ul>

For the case in the screenshot above, that text should not use an <ItemGroup> in the first place. There are other usage cases in the editor that need to be investigated though.

Still, this component is intended and documented to render a semantic list, while in practice it allows to be misused.

About the parent where <ItemGroup> is used into

Similar concerns raise when the <ItemGroup> is used within elements that can't contain a list.

Again, the <ItemGroup> is the equivalent of an <ul> unordered list. For example, an <ul> can't be used within a <button> element (or any element with role=button). If that was a HTML <ul>, it would be invalid HTML. Even if it's a div with role=list it's still semantically invalid.

One example of this is the 'Add background image' control in the global Styles > Background:

Image

In this case, there is a <button> element rendered by Dropdown, that contains an InspectorImagePreviewItem component which is an <ItemGroup> that contains span elements. In terms of equivalent HTML this would be:

<button>
    <ul> <-- Element ul not allowed as child of element button 
            <span> <-- Element span not allowed as child of element ul 
                Some content
            </span>
    </ul>
</button>

Step-by-step reproduction instructions

  • Go to Site Editor > Styles > Background
  • Inspect the source of the 'Add background image' control.
  • Observe it's a button element that contains an ItemGroup with role="list" which in turns contains only <span> elements.

Screenshots, screen recording, code snippet

No response

Environment info

No response

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Focus] Accessibility (a11y)Changes that impact accessibility and need corresponding review (e.g. markup changes).[Package] Components/packages/components[Type] BugAn existing feature does not function as intended

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions