department-of-veterans-affairs / va.gov-team

Public resources for building on and in support of VA.gov. Visit complete Knowledge Hub:
https://depo-platform-documentation.scrollhelp.site/index.html
284 stars 206 forks source link

508-defect-1❗[SCREENREADER]: Intercept Form - Checkboxes must announce legend consistently without being repetitive #26568

Open 1Copenut opened 3 years ago

1Copenut commented 3 years ago

508-defect-1 :exclamation: Launchblocker

Feedback framework

Definition of done

  1. Review and acknowledge feedback.
  2. Fix and/or document decisions made.
  3. Accessibility specialist will close ticket after reviewing documented decisions / validating fix.

Point of Contact

VFS Point of Contact: Trevor

User Story or Problem Statement

As a screen reader user, I want to hear the checkbox legend text when I arrow or tab to the first checkbox, but not hear that legend text repeated on every checkbox. This creates a high cognitive load and could make it more difficult to reason about the individual choices.

Details

Checkboxes are using a <label> for the group text instead of a <legend>, and aria-labelledby and aria-label to duplicate the label, then the individual label. These need to be refactored to a proper fieldset, legend, checkboxes pattern. Screenshot and code snippet below.

Acceptance Criteria

Proposed Solution (if known)

Let's remove the extra ARIA markup and use a standard markup pattern. I've excluded the Angular-specific markup for brevity.

<fieldset>
  <legend>Why did you select that rating? (Select all that apply)</legend>
  <div>
    <label for="reason-1">
      <input type="checkbox" id="reason-1" name="My need was addressed">
      My need was addressed
    </label>
    <label for="reason-2">
      <input type="checkbox" id="reason-2" name="My issue was resolved">
      My need was addressed
    </label>
  </div>
  ...
</fieldset>

WCAG or Vendor Guidance (optional)

Screenshots or Trace Logs

Screen Shot 2021-06-24 at 11 22 04 AM

holdenhinkle commented 3 years ago

I met with Trevor this morning and we reviewed the markup power this form, and compared it to his proposed solution, which is this:

<fieldset>
  <legend>Why did you select that rating? (Select all that apply)</legend>
  <div>
    <label for="reason-1">
      <input type="checkbox" id="reason-1" name="My need was addressed">
      My need was addressed
    </label>
    <label for="reason-2">
      <input type="checkbox" id="reason-2" name="My issue was resolved">
      My need was addressed
    </label>
  </div>
  ...
</fieldset>

Madalia's markup has a lot of problems. We talked about two ways to address the issues: 1) Ask Medallia to update their markup 2) Write some JavaScript to rebuild the form the way we want it

2 seemed like a hacky, brittle solution. And I was worried that making changes to the form would break whatever JavaScript is helping to power the form. Trevor and I decided this approach was not a good one and that's we'd try to talk with Medallia about our issues.

We decided I'd handle one, simple UI issue. The aria labels have a value that is derived from what should be the legend value and the checkbox value, like this:

aria-label="Why did you select that rating? (Select all that apply):My need was addressed"

For usability reasons, we want it just to be aria-label="My need was addressed"

I wrote a script to make these updates. Here's the pr - https://github.com/department-of-veterans-affairs/vets-website/pull/17856/files

Long story short, and I'll update this more tomorrow morning, we can't select any of the Medallia elements in the DOM.

I think Medallia elements are in the 'shadow dom'. You can’t access content of Shadow DOM from scripts outside of the Shadow DOM. Encapsulation is the purpose of Shadow DOM.

holdenhinkle commented 3 years ago

I'm going to give Jason Woodman a list of things we'd like Medallia to 'fix'.

holdenhinkle commented 3 years ago

So...

I ran this function beginning in the console on this page with an element in the Medallia form and it returned false:

function isInShadow(node) {
    for (; node; node = node.parentNode) {
        console.log(node);
        if (node.toString() === "[object ShadowRoot]") {
            return true;
        }
    }
    return false;
}

So, it's not a shadow dom issue.

The form is in an iframe that’s on a different domain - https://resource.digital.voice.va.gov/wdcvoice/5/forms/6/form1626210164730.html?formId=6&ty[…]splayType=lightbox&isSeparateFormTemplateFromData=true

We can’t get access to the internals of the form because of cross-site scripting.

@CBonade thinks we're loading it in an iframe is because we're not running angular on our site, so we're basically loading the form off another site that's running angular, which is a good theory.

Looks like he's right; here's the Angular app - https://resource.digital.voice.va.gov/resources/dist/assets/js/liveform-web-app-0a1dd48380.js

I assume there's a good reason why we're not hosting this on VA.gov. This offers lots of protections. However, if we can host this app on VA.gov then we could address some of the issues in these tickets.

pjhill commented 3 years ago

This issue with Medallia will be discussed in the meeting with Sarkis on Monday.

jwoodman5 commented 3 years ago

@pjhill @holdenhinkle I don't recall, what was the outcome of this one in the mtg today? Thanks.

holdenhinkle commented 3 years ago

There's nothing we can do to address the issues in this ticket ourselves. Sarkis is going to bring this to Medallia and see if they can update their app to resolve these issues.

jwoodman5 commented 3 years ago

Thanks!

joshkimux commented 1 year ago

@jwoodman5 @holdenhinkle has there been any update from Medallia on this issue? @artsymartha68 for awareness