Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added consistent aria levels to any role='heading' #5782

Merged
merged 2 commits into from
Aug 9, 2018
Merged

Added consistent aria levels to any role='heading' #5782

merged 2 commits into from
Aug 9, 2018

Conversation

micahgodbolt
Copy link
Member

@micahgodbolt micahgodbolt commented Aug 2, 2018

Pull request checklist

Description of changes

As per conversation, level 1 is reserved for page level headings (which our components will rarely be). So I've set everything at a default of 2, unless they are items inside of a component that already has a level 2, in which case it changes to level 3.

This switching behavior was already in contextual menu, so I made combobox consistent.

Focus areas to test

(optional)

Microsoft Reviewers: Open in CodeFlow

@micahgodbolt
Copy link
Member Author

@ekawatani @hoovercj @jspurlin @philipzloh @cschlechty

I found all of the role="heading" in fabric and tried to come up with a solution based on your feedback. Tell me if the above guidance appears correct.

@jspurlin
Copy link
Contributor

jspurlin commented Aug 2, 2018

Didn't mean to close the PR... The guidance is not correct in terms of an application or "widgets". aria-level can be relative/contextual, for example: menu, treeview, or tree. The current guidance seems to be thinking to literally about the h1 through h6 html element for traditional web pages

@micahgodbolt
Copy link
Member Author

can/should we add aria-level to our basecomponent? So it could be passed in to all components (and obviously only used by the ones that need it).

@micahgodbolt
Copy link
Member Author

nah....that'd infer that aria-level would be placed onto the root...no good

@jspurlin
Copy link
Contributor

jspurlin commented Aug 2, 2018

also, aria-level can be contextual so basing it off of a parent might not make sense

@@ -1119,7 +1121,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
const { onRenderOption = this._onRenderOptionContent } = this.props;

return (
<div key={item.key} className={this._classNames.header} role="heading">
<div key={item.key} className={this._classNames.header} aria-level={this.props.label ? 3 : 2} role="heading">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.props.label ? 3 : 2 [](start = 74, length = 24)

Please do leave a comment as to why label informs 3/2 here. To someone without the context that you have, this can look very arbitrary.

@@ -344,6 +344,8 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
required={required}
htmlFor={id + '-input'}
className={this._classNames.label}
aria-level={2}
role="heading"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt we'd want headings built in to combo boxes or other simple controls. Headings are mean to provide hierarchical page structure.

@micahgodbolt
Copy link
Member Author

So what are the places that actually need role="heading" and therefore aria-level? Is it just panel and dialog right now? And if so, can we simply go with a default value of 2, or do we need to leave that open for customization?

@cschlechty ?

@cschlechty
Copy link
Member

Having those as level 2 seems reasonable as long as we don't put them as descendants of things level 2 or lower.

@eikawata
Copy link

eikawata commented Aug 3, 2018

If aria-level is contextual, then the default value for these heading elements in popup boxes like ContexualMenu, and Panel should be 1 as this comment mentions. If it's set to 2, user will look for heading level 1 that doesn't exist.

We should open it up for customizing the aria-level if the component provides a way to custom-render parts of the component. For example, the Panel has a onRenderHeader prop for custom-rendering the header, and people may be injecting several headings in there.

@cschlechty
Copy link
Member

No. There should be only one heading of level 1 on a page. The levels are contextual in that it should make sense hierarchically, under h2s, you have h3s, etc. Where the controls are in the DOM structure will partially determine the level, so it needs some level of customization.

@hoovercj
Copy link
Member

hoovercj commented Aug 3, 2018

I'm a bit confused. For dialogs and such that appear overlaid over the content, with their root element perhaps being outside the main h1 of the page (last child of the body tag, for example, with the h1 being a few divs deep in the body), what is the expected heading level of the dialog heading?

Hierarchically in the dom it would be 1, but semantically on the page, perhaps 2? What does the spec suggest here?

And then consider a form on a page. Page header is level 1, form header is level 2, then if you start rendering menu items in the form, would their headings not be level 3+?

But what if, again, these menu items actually get rendered elsewhere in the dom but are "owned" by the form? In the dom they may not have a parent with a heading level. Does the spec give guidance here?

@metapzl
Copy link

metapzl commented Aug 3, 2018

As in my other comment, I don't really understand or see the correctness in having a heading inside a menu.

The point is not that there can only be one thing that is aria-level=1 onscreen. The argument that @cschlechty is making (that is supported by a lot of other developers in the accessibility space) is that there should only be one heading of aria-level=1 on a page. The argument that others are bringing up is that in HTML5, as we've evolved our understanding of a webpage (not just a document), having a heading of aria-level=1 for each different section may make sense. I can see that reason. However, I remain unconvinced that a menu is a different section, nor should it contain a heading.

@jspurlin
Copy link
Contributor

jspurlin commented Aug 3, 2018

It's technically incorrect to have an aria-level > 1 without all of the previous levels accounted for in the same section (in your example, a dialog)

@jspurlin
Copy link
Contributor

jspurlin commented Aug 3, 2018

@philipzloh these are heading in a menu, what else would you call them?

image

@cschlechty
Copy link
Member

cschlechty commented Aug 3, 2018 via email

@metapzl
Copy link

metapzl commented Aug 3, 2018

@jspurlin If I were super pedantic, that's incorrect / non-standard usage of menu? I understand that it shows up in our menus, but in a standard menu it should have been represented as:

  • Theme fonts
    • Arial Black
    • Times New Roman
    • Comic Sans MS
  • Other Options
    • Option d
    • Option e

In our case, we should probably represent this in pseudo-DOM as

<menu aria-label="font">
    <group aria-labelledby="themeid">
        <span id="themeid" aria-hidden="true">Theme Fonts</span>
        <menuitemradio>Arial Black</menuitemradio>
        <menuitemradio>Times New Roman</menuitemradio>
        <menuitemradio>Comic Sans MS</menuitemradio>
    </group>
    <group aria-labelledby="otherid">
        <span id="otherid" aria-hidden="true">Other Options</span>
        <menuitemradio>Option d</menuitemradio>
        <menuitemradio>Option e</menuitemradio>
    </group>
</menu>

@jspurlin
Copy link
Contributor

jspurlin commented Aug 3, 2018

@philipzloh and @cschlechty yep, that's an alternative approach to fix this and would actually result in a better readout

@micahgodbolt
Copy link
Member Author

Is there a final approach we all agree on? Is this PR good as is, or do we need to support custom aria-level values for these two surfaces.

And if there is further work to be done for the ComboBox and contextualMenu, can we put that into a separate issue?

@micahgodbolt
Copy link
Member Author

Let me toss out resolution for this PR.

  1. Remove aria-role="heading" from ComboBox and ContextualMenu. Sounds like there's a better approach suggested for improving those.
  2. aria-level needs to be customizable in the case that there is no other level 1 on the page. So I'll add props for panel and dialog to set that level.
  3. merge this PR :D

@jspurlin
Copy link
Contributor

jspurlin commented Aug 8, 2018

We should only remove the role=heading if we are also doing the aria-labelledby group (with aria-hidden on the actual heading element) approach. Otherwise if a use is consuming the menu with virtual focus it will announce those elements a " group" which is worse than it currently is.

Copy link
Member

@cschlechty cschlechty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually add menu sections per W3C, but this is a solid improvement.

@dzearing dzearing merged commit d5129e5 into microsoft:master Aug 9, 2018
@micahgodbolt micahgodbolt deleted the update-aria-level branch August 9, 2018 21:39
@microsoft microsoft locked as resolved and limited conversation to collaborators Aug 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
9 participants