Skip to content

Conversation

@austingreendev
Copy link
Contributor

@austingreendev austingreendev commented Jul 24, 2018

TL;DR: We have improved from an aggregate lighthouse accessibility score of 45% to 98.5% across ALL packages (with the remaining failures being lighthouse miss-fires) 🎉

  • BREAKING CHANGES?

⚠️ There are several breaking changes in this PR. This is just a collection of all changes that I completed. This should (and will) be broken up into several smaller PRs that can address the changes in more depth. ⚠️

Tooling Used

All three tools were used for the tests/assumptions performed during this process.

Here is a link to the lighthouse exports after the changes shown in this PR: https://drive.google.com/open?id=11bOPsxBof8gMa8Md0ZXhKzvMg0PHyVYq

These files can be viewed with https://googlechrome.github.io/lighthouse/viewer2x/

Description

Accessibility is important. All components within this repository are built to the W3C Design Patterns spec; so this means that everything is 100% accessible, right?

WRONG 😢 (this is react-buttons)

old-lighthouse-audit

The majority of component implementations are accessible, but our examples are currently lacking some good best practices. Some of this is a combination of color-contrast issues and customizations on top of react-styleguidist, but the worst offenders currently are the handwritten examples and some invalid assumptions about menu accessibility.

Currently all examples are hovering around the 40-60% lighthouse score. This PR is a collection of several breaking API changes, styleguidist improvements, and example updates. These will be split into several individual PRs, but I felt a background PR would help.

Detail

I've split this PR into 3 commits:

  • Breaking (and non-breaking) API Changes

    • Turns out sticking to the W3C spec doesn't provide everything. I'll go into depth in the individual PRs
    • Examples:
      • Can't apply two IDs to aria-describedby
      • aria-controls and aria-owns can only to reference elements that are rendered already (duh)
      • .etc
  • Example updates

    • Assorted aria-label and documentation changes
  • Styleguidist upgrades

    • Tried to use Garden colors throughout
    • Migrated propTypes table to use the Garden table component

Before:
old

After:
new

Learnings

Even thought we have static accessibility linting withjsx-a11y a large chunk of our codebase lives within the Markdown examples and isn't reachable with this tool. We should perform more frequent accessibility audits or find some additional ways of auditing this in an automated fashion.

Checklist

  • 👌 design updates are Garden Designer approved (add the
    designer as a reviewer)
  • 💅 view component styling is based on a Garden CSS
    component
  • 🌐 Styleguidist demo is up-to-date (yarn start)
  • ⬅️ renders as expected with reversed (RTL) direction
  • 💂‍♂️ includes new unit and snapshot tests
  • 📒 any new files are included in the packages src/index.js export
  • 📝 tested in Chrome, Firefox, Safari, Edge, and IE11

@allisonacs
Copy link

Happy to see this happen @Austin94! Less "do as I say," more "do as I do."

Copy link
Contributor

@ryanseddon ryanseddon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, so these all came out of running the styleguide through the chrome dev tools audit panel?

expect(input).toHaveProp('aria-describedby', `${CONTAINER_ID}--hint`);
});

it('excludes aria-describedby if option is provided', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'excludes aria-describedby if option is not provided'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Was going to save this for the separate PR, but depending on what we view as the most common scenario, we might have this default to false.

Updated for now.

</FieldContainer>
);

expect(findInput(wrapper)).toHaveProp('aria-describedby', null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work too?

expect(findInput(wrapper)).not.toHaveProp('aria-describedby')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately no. The syntax above would expect the prop to have undefined as a value, but is null as provided.

If we were to provide undefined through the render-prop it would actually show as undefined in the DOM. With null React is removing it from the attribute list.

role,
'aria-autocomplete': 'list',
'aria-haspopup': 'true',
'aria-owns': this.getMenuId(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this apply when the menu is open? I can't see that anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it does not. Since we are moving focus to the menu it seems to not be required? I ran AXE across all of the states in the menu and the only thing it picked up was us appending it to the body in a "non-landmark region" which would be something a consumer would customize.

@austingreendev
Copy link
Contributor Author

Nice, so these all came out of running the styleguide through the chrome dev tools audit panel

Unfortunately no. The overall scores did, but the majority of corrections were guided by the AXE plugin. It seems to be a lot more picky about things than the lighthouse audit and helped find some of the larger holes.

</Col>
</Row>
</Grid>
<div role="group" aria-label="State Usage Example">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these attributes apply to <Grid>? In other words, make role="group" automatic with the component and apply aria-label manually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are no added to the <Grid>

},
offset: {
fn: (data) => {
fn: data => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully grabbed by rebase on #65

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed with a rebase


exports[`Input renders RTL styling 1`] = `
<input
aria-invalid={false}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't {false} in these (and following) snaps unexpected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are defaulting this to false to match the "default" state (https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute).

Without any validation this would still be false. AXE didn't seem to find any issues with this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But shouldn't it be aria-invalid="false" rather than {false}? I haven't seen JSX syntax in snapshots before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvmd. Bogus expectations on my part here. 😳

import { zdFontSizeEpsilon, zdFontWeightSemibold } from '@zendeskgarden/css-variables';

const ArgumentsContainer = styled.div`
margin-bottom: 8px;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use xs spacing from css-variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

`;

const Heading = styled.div`
margin-bottom: 4px;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use xxs spacing from css-variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -0,0 +1,90 @@
.hljs {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can't access variables, it would be good to comment this file with selected color names from https://garden.zendesk.com/css-components/utilities/color/.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the equivalent color values as comments. I also updated all of the colors to match an equivalent in the palette so it should be a little clearer now.

@ryanseddon
Copy link
Contributor

AXE plugin

Oh weird I thought from this post that lighthouse actually internally uses AXE in the audit?

Copy link
Contributor

@ryanseddon ryanseddon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So next steps is to introduce smaller PRs for these changes?

@austingreendev
Copy link
Contributor Author

Oh weird I thought from this post that lighthouse actually internally uses AXE in the audit?

I think it does, it at least linked to the dequeue links that AXE provides, but it seems to be a sub-set of the audits that the standalone plugin uses.

So next steps is to introduce smaller PRs for these changes?

Yes. Probably 3-4

@austingreendev
Copy link
Contributor Author

Closing this now that all areas have been merged separately.

@austingreendev austingreendev deleted the agreen/accessibility branch October 2, 2018 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants