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

Improve details summary polyfill #57

Merged
merged 10 commits into from
Jan 30, 2015
Merged

Conversation

gemmaleigh
Copy link
Contributor

The current polyfill wasn't correctly detecting the "open" attribute and was firing twice in Chrome,
when the summary was clicked.

For now, it has two checks - first for native support, which uses the boolean "open" attribute. Then for non-native support, which checks for an "open" attribute with an empty value, otherwise "open" is
undefined (not present) and the details content should be closed.

For non-native support, an open or closed arrow (pointing right or down) is added, and styled to look like the native arrow in Chrome - depending on the initial "open" state. This arrow is hidden from assistive technology using role="presentation". Read the W3C Recommendation here.

A detailed explanation from Léonie:

<details role="group">

The implicit role for <details> should be "group". Since most browsers haven't implemented support for the element (let alone accessibility support), we need to apply this role manually – so that assistive technologies know that it's a container for a group of related content.

<summary role="button" aria-controls="details-content-0" tabindex="0" aria-expanded="false">…</summary>

[1] role="button *

The implicit role for <summary> should be "button", but as with <details> we need to provide the accessibility support explicitly using the role attribute.

[2] aria-controls="details-content-0"

  • Note: aria-controls is not consistently supported by assistive technologies.
    Those that do support it usually provide a keyboard shortcut that lets the user move focus to the start of the element being controlled. It is not expected behaviour for a screen reader to automatically start to speak the content of the disclosure widget when it opens.
  • It's also worth noting that VoiceOver/Safari doesn't support aria-controls in any case.

[3] tabindex="0" *

Without basic browser support for <summary> it can't be focused on with the keyboard. Using tabindex="0" places the element into the natural tab order of the page, so as someone using a keyboard tabs through the page they'll be able to focus on it in order to activate it.

[4] aria-expanded="false" *

The aria-expanded attribute informs assistive technologies that the <summary> element triggers the expansion/collapse of something. When focus first moves to the <summary> element, its state is announced as "collapsed", and once the button is activated it changes to "expanded".

Gemma Leigh added 8 commits January 27, 2015 15:07
This wasn’t correctly detecting the “open” attribute.

This is a quick fix to get feedback from Leonie and *needs* refactoring
and tests.

For now, it has two checks - first for native support, which uses the
boolean ‘open’ attribute.  Then for non-native support, which checks
for an ‘open’ attribute with an empty value, otherwise ‘open’ is
undefined (not present) and the details content should be closed.

This check is also used to either create an open or closed arrow
(pointing right or down) depending on the initial ‘open’ state.
In Chrome, this was triggering twice - both for click and “space”.

Removing the keydown event and adding a mouseup event, ensures this now
triggers when the enter or space key is pressed.

Anywhere `console.log` appears is commented out (rather than removed)
while this is tested further.
Simplify test page before asking for feedback from Leonie
JAWS reads “black down pointing triangle”, since using role=“button”
indicates that the button is expanded or collapsed, hide any
description of the arrow character.
The summary wasn’t accessible via the keyboard in IE6 & 7, so couldn’t
be tabbed to.

The bug is described here:
http://www.saliences.com/browserBugs/tabIndex.html

Using .tabIndex = 0, rather than .setAttribute('tabindex', '0') fixes
this.
@edwardhorsford
Copy link
Contributor

Really interesting summary. Thanks.

@tombye
Copy link
Contributor

tombye commented Jan 28, 2015

This is a great improvement and the summary of why the changes are needed is brilliant. 👍

@gemmaleigh gemmaleigh force-pushed the improve-details-summary-polyfill branch 2 times, most recently from 737c3c0 to e4487e2 Compare January 29, 2015 12:41
Gemma Leigh added 2 commits January 29, 2015 15:39
When the space key is used to open `<details>` the page scrolls. This
cancels the event and stops the page from scrolling.
In IE9 and below the `event` object [does not have a `preventDefault`
method](http://help.dottoro.com/ljwolcsp.php). Use `event.returnValue =
false;` for IE instead.
tombye added a commit that referenced this pull request Jan 30, 2015
@tombye tombye merged commit 2bf03cb into master Jan 30, 2015
@tombye tombye deleted the improve-details-summary-polyfill branch January 30, 2015 16:20
@tombye
Copy link
Contributor

tombye commented Feb 3, 2015

I've re-read the spec and my original presumption was incorrect so it's worth explaining why, mainly because it also explains why using aria-hidden is actually the advised approach.

In our use-case, the markup we tried for the arrow is:

<i class="arrow" role="presentation">▼</i>

The ▼ is a text node and a child of the <i> tag. The spec has this to say about how to handle descendants of elements given the role of 'presentation':

"...the user agent MUST expose content and descendant elements that do not have an explicit or inherited role of presentation."

The ▼ text node has a role of "text" so it will be exposed. This explains why the arrow was still being spoken when the <i> tag was given the 'presentation' role.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants