Paypal button label insertion interrupts screen reader - google-chrome

I have a "PayPal express checkout" button with a "Checkout" label which gets appended to the button after the page is loaded.
When the page starts loading, the screen reader (Chromevox in my case) starts reading the title of the page and then comes down to heading and to the Alert Box, if any. This flow gets interrupted in the middle when PayPal button calls for its label and the "Checkout" text gets rendered.
I've tried adding the aria-live="off" property to the parent of the PayPal button, but it didn't help. Any other way to prevent it from interrupting the screen reader?
You can check the same using ChromeVox on the PayPal Button example page - https://developer.paypal.com/demo/checkout/#/pattern/client
The Screenreader would start reading the title but a long bell sound would interrupt it with the PayPal animation.

Related

ARIA Live Regions for single page applications

I am new to accessibility of web pages. I have an application where the content of the body changes based on the header link clicks in an ajax call without page refresh. So the HTML content inside the body gets updated for each link click with different page content (table + button + information text).
My requirement here is the screen reader should announce the information text each time when the page gets loaded. Here the container is body (or an immediate div inside body) for all pages. So I have made it aria-live="polite", but every time page loads it is announcing the whole page content but I want to make it announce only the information text. Other elements of the page should be announced on focus/visit. I hope I can apply aria-live="off" for all other elements but I'm looking for any ideal solution for this. I cannot change the layout of the application.
Can some one help me on this. Thanks in advance.
SPA pattern best practices
You are essentially following a Single Page Application pattern. As such the method recommended for handling navigation is actually quite straight forward with two steps.
tell a user that navigation is about to occur (before navigation)
let a user know that loading is complete (after navigation).
before navigation (link click)
You need to signal to a user that a page is loading if you are using a SPA pattern (and therefore interrupting normal navigation). e.g. I click your link, you need to let me know that an action is being performed (loading.....) as you intercept the normal browser behaviour with e.preventDefault() or equivalent.
The simplest way is to use aria-live=assertive on a region that explains the page is loading. You can Google how to implement that correctly but essentially you would update the content of a hidden div (<div aria-live="assertive" class="visually-hidden">loading</div> with some loading message the second a link is clicked.
This should be done before any AJAX calls are made.
after navigation (new content loaded)
When the new page loads you need to manage focus.
The best way to do this is to add a level 1 heading (<h1>) to each page that has tabindex="-1". By using tabindex="-1" it means that the heading won't be focusable by anything other than your JavaScript so won't interfere with the normal document flow.
Once the page loads and the content has been populated fully the last action you perform in your JavaScript navigation function is to place the focus onto this heading.
This has two benefits:
it lets the user know where they are now
it also lets them know when the page load is complete (as AJAX navigation doesn't announce when the page is loaded in most screen readers).
At this point you may also want to clear the <div aria-live="assertive"> contents so that it is ready for further navigation.
Have you tried to wrap the "live zones" - where updates happen in div with aria-live="polite". Then screen reader will announces only these zones on updates.Don't wrap whole page or div in aria-live="polite".
<div aria-live="polite">
<p id="errorText">Announced on update</p>
</div>
<div>
other page sections..
</div>

Accessible, lengthy Terms of Service acceptance

A lengthy Terms of Service (TOS) is displayed in a scrolling div so the "Accept Terms" button remains visible beneath it in small viewports.
Does the scrolling div violate accessibility conventions, because:
a. a sighted user may click the "accept terms" button without reading the entire document, while
b. a person using a screen reader must hear the entire TOS before accessing the button?
Does providing a screen-reader "skip" link somehow invalidate the TOS acceptance?
Imagine https://stackoverflow.com/legal/terms-of-service/public in a scrolling div, with an acceptance button visible beneath it.
Is it required to scroll the div to the bottom before the Accept button is activated?
If the accept button is always activated then the answer is simple, make sure that the accept button is a valid tab selectable target and is either a button (same page) or link (another page).
Screen Reader users are used to navigating past Terms of Service (ToS) by looking for the next link or button.
If the accept button is only activated once the div has been scrolled to the bottom - this is where you may need a minor redesign.
The whole purpose of the scroll to bottom is to 'confirm'** that a user has read the ToS.
Instead have a button that shows the ToS in a (second) modal and locate the close button after all of the text within that modal.
Only activate the Accept button once the close button in the ToS (second) modal has been pressed.
This way you can 'prove' that the terms have been read.
** I put confirm in quotes here here because let's face it nobody actually reads them even if you implement this out-dated practice, they simply just have to scroll a box before ignoring the ToS. If you can make the decision go with the first option of just a link or button to Accept.
Idea: If you want you could use some 'visually hidden' (CSS trick) skip link that says "yeah I don't read Terms of Service but I accept them anyway, take me to the accept button" and jump them to the accept button......no idea if that is legally compliant though :-)

ARIA friendly popover that can be tabbed out of

I want to create a popup next to some data that contains a few input fields. Let's pretend that the we have the following document structure
<input name="before-the-data" type="text />
<div id="the-data"><!-- presents some data --></div>
<input name="after-the-data" type="text />
When you tab forward from before-the-data the popover should open and focus should go to the first input in this popover. This popover is appended to the body kinda of like Modal from material-ui so that it lies above the rest of the content. Similarly the popover should open when you tab backwards from after-the-data.
The popover should behave as if it were inside #the-data for navigation purposes but the actual position would be at the end of <body> for presentation purposes.
To achieve this effect, I set tabindex="0" on #the-data and trigger opening the modal and shift focus into it. This works fine so far.
Now for the question: How do I best create the following effect?
You should be able to navigate back out of the modal. My idea was this: When focus shifts from it or the user clicks outside the modal, we close it and restore focus to the element that had focus before it opened up. This can be done with a simple onblur handler and a onclick on a backplane. To support tabbing, the resulting modal looks like this:
<div id="backplane" onclick="closeAndRestoreFocus()"
onfocusout="checkCloseAndRestoreFocus()">
<div id="beforecanary" onfocus="shiftFocusBefore()" tabindex="0"/>
<!-- popover content -->
<div id="aftercanary" onfocus="shiftFocusAfter()" tabindex="0"/>
</div>
You can see that I added two divs that you can tab to beforecanary and aftercanary. When they get focused they shift focus to before-the-data and after-the-data respectively, to simulate as if the popover was actually inside #the-data.
At this point, you hopefully have understood what I am trying to create. Thus, the question: How good is this approach in general with respect to accessibility and how can I make sure I follow best practices of WAI-ARIA?
we close it and restore focus to the element that had focus before it opened up
That might be considered a tab trap, 2.1.2 No Keyboard Trap. Isn't the element that had focus before the popup the #the-data? So if I tab from before-the-data to #the-data, the popup will open. If I press esc to close the popup (you didn't mention that esc would close the popup but it should), the focus goes back to #the-data, which will automatically open the popup again, won't it? (Because onfocus() ran again.)
If I just tab through the entire process, I think it would work. It's just the dismissing of the popup that causes the problem. Tabbing straight through everything would move focus from before-the-data to #the-data to the elements in the popup to after-the-data then to the rest of the page, right?
When tabbing backwards, from after-the-data to #the-data, is the focus moved into the last element in the popup? Since I'm tabbing backwards, it needs to be on the last item so that I can continue tabbing backwards through the popup and then to before-the-data.
The popover should behave as if it were inside #the-data for navigation purposes but the actual position would be at the end of <body> for presentation purposes.
If the popup is in the DOM at the end, that would not allow a natural tab order. You can certainly put it there but then you have to manage the tab order. It would be much simpler if the popup was truly part of #the-data. Then the browser handles the tab order naturally.
You also have to be careful with automatically opening a popup but it might be a violation of 3.2.1 On Focus. See "Example of a Failure: A help dialog". It sort of describes what you are doing but is a little different. In the failure example, focus is moving to an input field, and the popup opens automatically and the focus moves from the input to the popup. Your case is a little different because you move the focus off the input first (or before-the-data) and then the popup displays, which would not violate 3.2.1. I just wanted to point this out in case you change your interaction model.
So in summary, your current behavior is kind of like a skip link. Skip links are often implemented as "hidden" links that only become visible when you tab to them and allow you to jump to a location on the page. The fact that they become visible upon focus is how your popup works (since it too becomes visible when it receives focus). The difference is that skip links do not dismiss if you press esc. They do dismiss if you click outside of them. I think that's the behavior you're trying to mimic. If you ignore my comment earlier that esc should dismiss your popup, then you'll be ok. I only had that comment because it sounded like your popup was like a modal dialog.

Website "jumps" up and covers input when typing with iPhone's virtual keyboard

I've a website with a textarea at the bottom. When I focus the textarea, the keyboard slides up and pushes the website up so I can see the textarea. As soon as I start typing, the website jumps back down and now the keyboard overlays the input and I'm not able to see what I'm typing.

Pressing the back button does not trigger <body>'s OnLoad

My checkout cart displays (1) an animation for "Processing Order..." after the 's been (2) submitted and the card is being processed in a php script. However, there's a bug triggered when the user has reached the "order accepted" page, and pressed the back button. The "Processing Order..." animation is still displayed.
(1) The processing display is shown like:
<div style="position:absolute;display:none;" id="animation">
<img src="animation.gif"/>
</div>
(2) When the button is submitted, the javascript used:
onClick="document.getElementById('animation').style.display='block';
document.the_form.submit();"
So, the button is clicked, the animation displayed, the form submitted, and the card is processed, and the user is on a new page.
When the user clicks back, we should expect a page without the animation. But, onLoad isn't triggered, and the last state of the animation (displayed) is saved.
Any idea how to remove the animation when the user returns to the page?
Inspired by Adam A's comment, you could hide the animation when the user is leaving the page (through form submit is the normal route, I would suspect) so if/when coming back to the page, the animation isn't shown.
One way to achieve this is adding the hiding code to HTML body's onunload event.
<body onunload="document.getElementById('animation').style.display='none';">
In most modern browsers, clicking back doesn't reload the page, it just displays it from memory as it last remembered it (as this is likely to be the desired behaviour).
In my limited experience of UI design, I'm not sure why you would want users to click the 'back' button after submitting an order, instead you should provide a link that takes them forward to the next task they may wish to complete, or, forward them onto a new page that has useful tasks and simply displays a message somewhere that says "Thanks, your order is accepted".