Skip to content

Commit

Permalink
A11Y changes for Stories (#27820)
Browse files Browse the repository at this point in the history
* A11Y changes for Stories

- Turn mute/unmute into a real button.
- Restore focus outline for the pagination buttons.
- Use video `aria-label` in vertical rendering.

* - Set `aria-hidden` explicitly on story pages.
- Make attachments `aria-live`

* - Mark the story itself as a live region
- Make every page a region

* Label the attachment close button

* - Hide the closed share menu
- Hide progress bar from screen readers

* - Label the pagination buttons
- Mark the bookend as `aria-hidden` when hidden

* Fix lint
  • Loading branch information
cramforce committed Apr 21, 2020
1 parent fcf2c2f commit 62248e7
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 9 deletions.
3 changes: 3 additions & 0 deletions extensions/amp-story/1.0/amp-story-draggable-drawer.js
Expand Up @@ -147,6 +147,7 @@ export class DraggableDrawer extends AMP.BaseElement {
);

this.element.appendChild(templateEl);
this.element.setAttribute('aria-hidden', true);
}

/** @override */
Expand Down Expand Up @@ -487,6 +488,7 @@ export class DraggableDrawer extends AMP.BaseElement {
this.storeService_.dispatch(Action.TOGGLE_PAUSED, true);

this.mutateElement(() => {
this.element.setAttribute('aria-hidden', false);
resetStyles(this.element, ['transform', 'transition']);

if (!shouldAnimate) {
Expand Down Expand Up @@ -530,6 +532,7 @@ export class DraggableDrawer extends AMP.BaseElement {
this.storeService_.dispatch(Action.TOGGLE_PAUSED, false);

this.mutateElement(() => {
this.element.setAttribute('aria-hidden', true);
resetStyles(this.element, ['transform', 'transition']);

if (!shouldAnimate) {
Expand Down
3 changes: 2 additions & 1 deletion extensions/amp-story/1.0/amp-story-page-attachment.js
Expand Up @@ -97,6 +97,7 @@ export class AmpStoryPageAttachment extends DraggableDrawer {
});

toggle(this.element, true);
this.element.setAttribute('aria-live', 'assertive');
}

/**
Expand All @@ -106,7 +107,7 @@ export class AmpStoryPageAttachment extends DraggableDrawer {
buildInline_() {
this.headerEl_.appendChild(
htmlFor(this.element)`
<span class="i-amphtml-story-page-attachment-close-button"
<span class="i-amphtml-story-page-attachment-close-button" aria-label="X"
role="button">
</span>`
);
Expand Down
2 changes: 2 additions & 0 deletions extensions/amp-story/1.0/amp-story-page.js
Expand Up @@ -358,6 +358,7 @@ export class AmpStoryPage extends AMP.BaseElement {
true /* callToInitialize */
);
this.setPageDescription_();
this.element.setAttribute('role', 'region');
}

/** @private */
Expand Down Expand Up @@ -1184,6 +1185,7 @@ export class AmpStoryPage extends AMP.BaseElement {
}

this.element.setAttribute('distance', distance);
this.element.setAttribute('aria-hidden', distance != 0);
this.registerAllMedia_();
if (distance > 0 && distance <= 2) {
this.findAndPrepareEmbeddedComponents_();
Expand Down
3 changes: 2 additions & 1 deletion extensions/amp-story/1.0/amp-story-share-menu.js
Expand Up @@ -46,7 +46,7 @@ export const VISIBLE_CLASS = 'i-amphtml-story-share-menu-visible';
*/
const getTemplate = (element) => {
return htmlFor(element)`
<div class="i-amphtml-story-share-menu i-amphtml-story-system-reset">
<div class="i-amphtml-story-share-menu i-amphtml-story-system-reset" aria-hidden="true" role="alert">
<div class="i-amphtml-story-share-menu-container">
<span class="i-amphtml-story-share-menu-close-button" role="button">
&times;
Expand Down Expand Up @@ -230,6 +230,7 @@ export class ShareMenu {
if (!this.isSystemShareSupported_) {
this.vsync_.mutate(() => {
this.element_.classList.toggle(VISIBLE_CLASS, isOpen);
this.element_.setAttribute('aria-hidden', !isOpen);
});
}
this.element_[ANALYTICS_TAG_NAME] = 'amp-story-share-menu';
Expand Down
1 change: 1 addition & 0 deletions extensions/amp-story/1.0/amp-story-system-layer.css
Expand Up @@ -65,6 +65,7 @@
width: 48px !important;
cursor: pointer !important;
border-radius: 50% !important;
border-width: 0 !important;
box-sizing: border-box !important;
position: relative !important;
pointer-events: auto !important;
Expand Down
9 changes: 3 additions & 6 deletions extensions/amp-story/1.0/amp-story-system-layer.js
Expand Up @@ -161,18 +161,16 @@ const TEMPLATE = {
],
},
{
tag: 'div',
tag: 'button',
attrs: dict({
'role': 'button',
'class': UNMUTE_CLASS + ' i-amphtml-story-button',
}),
localizedLabelId:
LocalizedStringId.AMP_STORY_AUDIO_UNMUTE_BUTTON_LABEL,
},
{
tag: 'div',
tag: 'button',
attrs: dict({
'role': 'button',
'class': MUTE_CLASS + ' i-amphtml-story-button',
}),
localizedLabelId:
Expand All @@ -189,9 +187,8 @@ const TEMPLATE = {
localizedLabelId: LocalizedStringId.AMP_STORY_SHARE_BUTTON_LABEL,
},
{
tag: 'div',
tag: 'button',
attrs: dict({
'role': 'button',
'class': SIDEBAR_CLASS + ' i-amphtml-story-button',
}),
localizedLabelId: LocalizedStringId.AMP_STORY_SIDEBAR_BUTTON_LABEL,
Expand Down
1 change: 1 addition & 0 deletions extensions/amp-story/1.0/amp-story.js
Expand Up @@ -459,6 +459,7 @@ export class AmpStory extends AMP.BaseElement {
);
});
}
this.element.setAttribute('aria-live', 'polite');
}

/**
Expand Down
1 change: 0 additions & 1 deletion extensions/amp-story/1.0/pagination-buttons.css
Expand Up @@ -99,7 +99,6 @@
transition: 150ms opacity linear, 350ms transform linear!important;
cursor: pointer!important;
z-index: 100002!important;
outline: none!important;
}

.i-amphtml-story-desktop-fullbleed .i-amphtml-story-button-move {
Expand Down
13 changes: 13 additions & 0 deletions extensions/amp-story/1.0/pagination-buttons.js
Expand Up @@ -34,11 +34,13 @@ const BackButtonStates = {
className: 'i-amphtml-story-back-close-bookend',
action: Action.TOGGLE_BOOKEND,
data: false,
label: 'Close bookend',
},
HIDDEN: {className: 'i-amphtml-story-button-hidden'},
PREVIOUS_PAGE: {
className: 'i-amphtml-story-back-prev',
triggers: EventType.PREVIOUS_PAGE,
label: 'Previous page',
},
};

Expand All @@ -48,15 +50,19 @@ const ForwardButtonStates = {
NEXT_PAGE: {
className: 'i-amphtml-story-fwd-next',
triggers: EventType.NEXT_PAGE,
// TODO: Here and other labels: i18n.
label: 'Next page',
},
REPLAY: {
className: 'i-amphtml-story-fwd-replay',
triggers: EventType.REPLAY,
label: 'Replay',
},
SHOW_BOOKEND: {
className: 'i-amphtml-story-fwd-more',
action: Action.TOGGLE_BOOKEND,
data: true,
label: 'Show bookend',
},
};

Expand Down Expand Up @@ -106,8 +112,14 @@ class PaginationButton {

/** @public @const {!Element} */
this.element = renderAsElement(doc, BUTTON);
/** @public @const {!Element} */
this.button_ = devAssert(
this.element.querySelector('button'),
'Expect to find a button'
);

this.element.classList.add(initialState.className);
this.button_.setAttribute('aria-label', initialState.label);

this.element.addEventListener('click', (e) => this.onClick_(e));

Expand All @@ -125,6 +137,7 @@ class PaginationButton {
}
this.element.classList.remove(this.state_.className);
this.element.classList.add(state.className);
this.button_.setAttribute('aria-label', state.label);
this.state_ = state;
}

Expand Down
1 change: 1 addition & 0 deletions extensions/amp-story/1.0/progress-bar.js
Expand Up @@ -146,6 +146,7 @@ export class ProgressBar {
}

this.root_ = this.win_.document.createElement('ol');
this.root_.setAttribute('aria-hidden', true);
this.root_.classList.add('i-amphtml-story-progress-bar');
this.storyEl_.addEventListener(EventType.REPLAY, () => {
this.replay_();
Expand Down
1 change: 1 addition & 0 deletions extensions/amp-story/1.0/semantic-render.js
Expand Up @@ -66,6 +66,7 @@ export function renderPageDescription(page, videos) {
videos.forEach((videoEl) => {
addTagToDescriptionEl('p', videoEl.getAttribute('alt'));
addTagToDescriptionEl('p', videoEl.getAttribute('title'));
addTagToDescriptionEl('p', videoEl.getAttribute('aria-label'));
fetchCaptions(page, videoEl).then((text) => {
addTagToDescriptionEl('p', text);
});
Expand Down

0 comments on commit 62248e7

Please sign in to comment.