Page MenuHomePhabricator

[Bug] Mobile sections should announce their collapsed/expanded state to screen-readers.
Closed, ResolvedPublic3 Estimated Story PointsSpike

Description

In the Minerva skin, sections are collapsed by default on mobile devices, however, this information is not conveyed to screen-readers. When tabbing through sections, all that people using a screen-reader hear is the name of the section, with no indication that the section is collapsed and can be expanded to reveal more content.

Compare the current behaviour to another website like apple.com, where the collapsed sections are announced to screen-readers (on Safari, MacOS desktop)

Demo videoCollapsed stateexpanded state
m.wikipedia.org demo videoHeading level 2 heading name, clickablepress heading level 2, heading name
apple.com demo videoheading name, collapsed, buttonheading name, expanded, button

Note that screen-readers vary widely in their verbosity level and what is read aloud.
On iOS for example, section headings are read as:
"heading name, Heading level 2, table start" and then "Edit, Heading level 2, link, table end"

iOS demo video

The headings are not inside a table, but they’re interpreted as such because display: table; is used in the CSS. The word “clickable” is also omitted on iOS, which leaves no indication that the heading contains any content. Announcing the CSS table might be a bug in Safari, but it might still be worth replacing the display:table layout with something more… flexible 😉

Developer notes

ARIA attribute changes

  • Remove the erroneously placed aria-expanded attribute from the section content, which exists in Toggler.js#153. Added in c8d446be9164 in 2013.
  • Remove the aria-pressed attribute. This is meant for toggle-buttons like checkboxes or radios.
  • Remove the aria-haspopup="true" (meant for modals or popup-menus) from the section heading. The aria-expanded should suffice.
  • Add the aria-expanded="true/false" attribute to the section heading.

HTML Changes
The heading should be announced as a button, but if we add role=button then the heading might loose it's semantic value as a heading (i.e. I might not be announced when you ask the screen-reader to read all the headings on the page).
Therefore the heading should contain a button inside it. It already features a span which we could assign role=button to accomplish exactly that.

<h2 class="section-heading collapsible-heading...">
    <toggle-arrow/>
    <span class="mw-headline" aria-expanded="false" aria-controls="content-id">Section heading text</span>
    <edit-icon/>
</h2>
<div id="content-id">...</div>

The only notable change would be the focus outline moving from h2 to the span.mw-headline, which seems acceptable.
Toggle arrow remains clickable as well.

As to the announcement of CSS tables, a newer flex-box-based layout might be more appropriate for these headings.

This article https://inclusive-components.design/collapsible-sections/ provides a good overview of how collapsible sections should behave.

Acceptance Criteria

  • [- ] When tabbing through sections with a screen-reader, the screen-reader should say “expanded” or “collapsed” for each section. This is achieved with the aria-expanded attribute.
  • [- ] The section headings should also also announce themselves as buttons.
  • [- ] When collapsing or expanding a section with a screen-reader, the reader should announce the new state of the section.

Stretch goals

  • Section heading should not be announced as tables. – Seems to be a know NVDA bug

QA

  • QA should prioritize Android or iOS for this behaviour, since mobile devices have sections collapsed by default.
  • Needs to be tested on simplified talk pages as well as they are featuring a slightly different DOM than article pages.

QA Results - Prod

ACStatusDetails
1T218404#6222221
2T218404#6222221

Event Timeline

Jdlrobson renamed this task from Mobile sections should announce their collapsed/expanded state to screen-readers. to [Bug] Mobile sections should announce their collapsed/expanded state to screen-readers..Mar 15 2019, 10:01 PM
Jdlrobson added subscribers: ovasileva, Jdlrobson.

This seems clearly defined to me. @ovasileva should provide a priority.

potentially replaced by role=button

Note that this is an h2 element. Setting role=button overrides the implied heading role of the h2. Originally in the spec, it was possible to have role="heading button", but this was recently dropped from the aria/html spec. You now need 2 (nested) elements if you want to make a h2 a button.

Seems most screenreaders will announce any clickable element however, even if not a button, so maybe not needed to have both roles here.

The headings are not inside a table, but they’re interpreted as such because display: table; is used in the CSS.

P.S. I don't see this behaviour on Safari 12 and Mac OS 10.14.3.. Might be a VO setting however. Also I consider this a bug, CSS should not change the role of the DOM like that. Suggest filing a webkit ticket.

ovasileva triaged this task as Medium priority.Mar 18 2019, 12:32 PM

You now need 2 (nested) elements if you want to make a h2 a button.

@TheDJ thanks for pointing that out. I modified the description to note that we'll have the change the HTML markup and add a <button> element.
And yeah, the display: table is probably a bug in iOS, it's been identified as such on this Level Access wiki page so I'll probably file a bug report for it.

The best thing here would be not to collapse the sections at all as screen readers take headings as one possible navigational jump target already. But given technical obstacles that seems out of reach.
+1 to removing the misleading, misappropriated ARIA roles as a first step.

The best thing here would be not to collapse the sections at all as screen readers take headings as one possible navigational jump target already. But given technical obstacles that seems out of reach.

I think this approach is worthy of investigation, and since this ticket is in the "needs analysis" column, we should investigate the feasibility of this approach over the one presented in the description.

The question posed here is "is it possible to create collapsible sections that are always visible to screen-readers, regardless of their collapsed/expanded state". This solution would eliminate the need for a button in the headers and the aria attributes altogether, which would simplify the code substantially.

Jdlrobson added a project: Spike.

Sounds like a spike? Should we subtask or create a spike?

Jdlrobson lowered the priority of this task from Medium to Low.Apr 4 2019, 10:10 PM

Following on from our retro conversation, I think the appropriate action here is low given our Advanced Mobile Contributions commitments right now.

@Jdrewniak As of now, collapsing and expanding is not bound to any animation or transition. With that .collapsible-block:not(.open-block) could have screen-reader mixin applied, to make them available only for screen readers as long as they are collapsed.
That would also imply removing all current, falsely applied ARIA roles, like aria-haspopup

@Volker_E I took a look at this approach today, essentially making the text "screen-reader only" when a section is in the collapsed state.
This works pretty well, simply by removing the aria attributes, keeping tabindex=0 on the headings, and using the following CSS to show/hide the sections instead of display: none;

.client-js {
	.collapsible-block {
		height: 1px;
		width: 1px;
		overflow: hidden;

		&.open-block {
			height: auto;
			width: auto;
			overflow: initial;
		}
	}
}

The only downside to this approach is that with keyboard navigation, tabbing through the page still tabs through the hidden sections. However, I don't think this is a big issue because sections are only hidden by default on mobile, and for sighted users it's obvious that the sections are collapsed.

Performance
However, a larger concern with this approach might be loading performance. I'm no expert in this, but I have a feeling that browsers might be smart enough not to render/paint display: none elements (maybe @Krinkle can tell me if that's true).

When I compared the rendering of List_of_compositions_by_Johann_Sebastian_Bach on my local, I think the "screen-reader only" method of hiding sections might have a big negative impact on rendering performance.

Screen Shot 2019-04-26 at 15.14.35.png (1×2 px, 743 KB)
Screen Shot 2019-04-26 at 15.13.21.png (1×2 px, 761 KB)
sections hidden with display:nonesections hidden with "screen-reader only" technique

As far as I can see, the difference in rendering is massive.

@Jdrewniak Great write-up, display: none is removing the element(s) from render tree therefore I was sure there's a performance impact. Still surprising how big it is on a page of around 19.500 DOM elements given that browsers are very fast in rendering nowadays.

To move this forward, how about we provide patches for removal of the false ARIA attributes for the beginning, as they are undisputedly wrong?

ovasileva raised the priority of this task from Low to Medium.May 28 2019, 4:41 PM
Restricted Application changed the subtype of this task from "Task" to "Spike". · View Herald TranscriptMay 28 2019, 4:41 PM

Instead of inventing another button, which has two possible disadvantages:

  • Cross-browser rendering issues, even though we set all: inherit on it, there's too much rendering quirks risk, that can I wouldn't open if not absolutely necessary
  • We have to add an element, which means a huge code refactoring, and I don't see the necessary time budget given

we could just add aria-hidden: true on indicator (=> doesn't seem necessary as indicator doesn't carry any readable text anyways) and the rest of the ARIA attributes on the heading span.mw-headline.
Simple, and hopefully beautiful.

Change 596800 had a related patch set uploaded (by VolkerE; owner: VolkerE):
[mediawiki/extensions/MobileFrontend@master] Toggler: Remove wrong ARIA attributes

https://gerrit.wikimedia.org/r/596800

Change 596801 had a related patch set uploaded (by VolkerE; owner: VolkerE):
[mediawiki/extensions/MobileFrontend@master] Toggler: Re-introduce ARIA attributes and add button role on collapsible headings

https://gerrit.wikimedia.org/r/596801

On the small change of keyboard focus outline: Without historical context, is the reason for the arrow icon coming via Icon() to standardize icon implementation in MF? For this use case I don't think it's the best choice. Or where there other reasons behind?

If giving up on Icon() and relying on CSS background-image and make it part of .mw-headline we could establish a focus outline as before in the most simple way. I guess that's unwanted.

Change 596801 abandoned by VolkerE:
Toggler: Re-introduce ARIA attributes and add button role on collapsible headings

Reason:
Merged into I3ddd9f2afe36c53b67f4

https://gerrit.wikimedia.org/r/596801

is the reason for the arrow icon coming via Icon() to standardize icon implementation in MF?

@Volker_E I think the reason for the icon coming in via the MobileFrontend Icon() class is that the icon only makes sense when the javascript responsible for toggling the sections is loaded as well. If you load the page without JS, the icon is not there, because then there is no way to toggle the sections either.

is the reason for the arrow icon coming via Icon() to standardize icon implementation in MF?

@Volker_E I think the reason for the icon coming in via the MobileFrontend Icon() class is that the icon only makes sense when the javascript responsible for toggling the sections is loaded as well. If you load the page without JS, the icon is not there, because then there is no way to toggle the sections either.

Section collapsing is actually only possible in the mobile domain. It provides the feature for other skins like Vector (with styling issues) too.. https://en.m.wikipedia.org/wiki/Spain?useskin=vector

Desktop Minerva doesn't have collapsed icons.

Change 596800 merged by jenkins-bot:
[mediawiki/extensions/MobileFrontend@master] Toggler: Remove wrong ARIA attributes & re-introduce them correctly

https://gerrit.wikimedia.org/r/596800

Excellent, thanks so much @Jdrewniak for the great write-up and both you and @Jdlrobson for the quick follow-up!

ovasileva set the point value for this task to 3.May 20 2020, 4:11 PM

Feedback from Matthew Enigk of AFB:

Glad to see it fixed. I gave it a quick check and it looks good! […]

Looking at that long standing task, I noticed the stretch goal of "Section heading should not be announced as tables." This is an issue we have encountered in the past and mostly seems to be an NVDA/Chrome issue on desktop. For mobile we've also seen it on iOS so it may be more of a webkit related issue than NVDA specific.

If you aren't already tracking it, here is currently an open issue with NVDA for it https://github.com/nvaccess/nvda/issues/9760

So we might look into a bright future.

@Volker_E cool! regarding the CSS tables being spoken as tables, I've only seen it on iOS, and I think it's been fixed a few versions back. If it's causing problems on other platforms though, we could avoid it entirely by switching the headers to a flex box layout instead (we're talking about the section headings here, where display:table is used to align the edit icons to the right).

@Jdrewniak My point of view is, we shouldn't work around such a software bug, if it's filed and affecting numerous websites at once. display: flex is excluding more users than display: table.

Volker_E updated the task description. (Show Details)
Edtadros subscribed.

Test Result - Prod

Status: ✅ PASS
Environment: enwiki/simple
OS: iOS13.5.1
Browser: Safari
Device: iPhone 11 Max Pro
Emulated Device: NA

Test Artifact(s):

QA steps

✅ AC1: QA should prioritize Android or iOS for this behaviour, since mobile devices have sections collapsed by default.
✅ AC2: Needs to be tested on simplified talk pages as well as they are featuring a slightly different DOM than article pages.

I checked this on iOS and it announces the section heading and the whether it is expanded or collapsed. This worked in enwiki and simple.

ovasileva updated the task description. (Show Details)

All done!