{"action":"created","comment":{"url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/comments/134727357","pull_request_review_id":58049267,"id":134727357,"diff_hunk":"@@ -0,0 +1,112 @@\n+layout: post\n+title: 'Improving accessibility with accessibility acceptance criteria'\n+tags:\n+  - gds\n+  - accessibility\n+categories:\n+  - projects\n+date: 2017-07-29\n+---\n+\n+Accessibility acceptance criteria are a list of criteria that a user interface must meet to be considered accessible. They define what makes the building blocks of a user interface accessible and give teams criteria to test against. They a place to record accessibility decisions.\n+\n+[As Alistair Duggan said](https://accessibility.blog.gov.uk/2016/05/16/what-we-mean-when-we-talk-about-accessibility-2/):\n+\n+> it is lack of awareness that most commonly results in things being inaccessible\n+\n+Accessibility acceptance criteria raise awareness about what accessible means in a specific context. They’re more specific than general accessibility guidance, such as the Web Content Accessibility Guidelines (WCAG).\n+\n+At Government Digital Service what we build must be accessible. It’s one of our design principles, “[This is for everyone](https://www.gov.uk/design-principles#sixth)”:\n+\n+> Accessible design is good design. Everything we build should be as inclusive, legible and readable as possible. [...] The people who most need our services are often the people who find them hardest to use. Let’s think about those people from the start.\n+\n+By defining accessibility acceptance criteria upfront we are forced to think about accessibility from the start. It helps us to [consider the range of users](https://accessibility.blog.gov.uk/2016/05/16/consider-the-range-of-people-that-will-use-your-product-or-service/). The criteria become a starting point for building accessible things.\n+\n+## Example criteria\n+\n+### Accessible autocomplete\n+\n+At GDS we first used accessibility acceptance criteria when building the [accessible autocomplete](https://github.com/alphagov/accessible-autocomplete). Theodor Vararu, Léonie Watson and Ed Horsford defined the following [autocomplete accessibility criteria](https://github.com/alphagov/accessible-autocomplete/blob/master/accessibility-criteria.md) — the necessary behaviours that an autocomplete needs to meet to be usable by assistive technologies:\n+\n+> The field with autocomplete must:\n+> 1. Be focusable with a keyboard\n+> 2. Indicate when it has keyboard focus\n+> 3. Inform the user that it is an editable field\n+> 4. Inform the user if there is a pre-filled value\n+> 5. Inform the user that autocomplete is available\n+> 6. Explain how to use autocomplete\n+> 7. Inform the user that content has been expanded\n+> 8. Inform the user when there are matches, or if there are no matches\n+> 9. (Optional) Inform the user how many matches are currently available\n+> 10. Inform the user as the number of matches changes\n+> 11. Enable the user to navigate the available matches using touch or keyboard\n+> 12. Inform the user when a match is selected\n+> 13. (Optional) Inform the user which number the currently selected match is (1 of 3 for example)\n+> 14. Inform the user if a match is pre-selected\n+> 15. Enable the user to confirm the selected match\n+> 16. Inform the user when a match is confirmed\n+> 17. Return focus to the editable field when a selected match is confirmed\n+\n+### GOV.UK publishing components\n+\n+On the GOV.UK Publishing Frontend team we are breaking down our pages into reusable component blocks which are documented in a component guide. A component is a package comprised of template, style, behaviour and documentation that follows our [component principles](https://github.com/alphagov/govuk_publishing_components/blob/master/docs/component_principles.md).\n+\n+We are defining accessibility acceptance criteria for each component to help us assess the accessibility of the existing code and to ensure we can iterate on these component designs without breaking accessibility.\n+\n+Our components are less complex than an autocomplete, but our criteria still highlight important accessibility needs.\n+\n+#### Navigating translations\n+\n+For a component that lists links to translations of the current page we identify the following criteria:\n+\n+> The translation navigation links must identify the language of the link for correct screen reader pronunciation\n+\n+While this is true for all words that are in a language different to the main content’s language, it is especially important to consider in the context of this component. Here there is a high risk of introducing an accessibility barrier.\n+\n+#### Banners\n+\n+On a banner component that places white text on a blue background we use the criteria to highlight the importance of contrast ratios:\n+\n+> The banner must have a text contrast ratio of at least 4.5:1 against the background colour to meet [WCAG AA](https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast)\n+\n+While all text must have a sufficient contrast ratio, given this component’s use of colour it has an increased risk of introducing a barrier.\n+\n+Note also that WCAG AA defines different ratios for large and small text, we’ve found that the definition of large and small can be misinterpreted. Using one contrast ratio for all text eliminates any chance of mistake.\n+\n+## Criteria maintain accessibility\n+\n+When building user interfaces we do our best to ensure they are accessible. But without a definition of what made it accessible it’s hard to iterate on and too easy to introduce accessibility regressions. Even when we know it’s been built well, and that effort went into making it accessible – how do we make changes without breaking accessibility? What stops our new definition of accessibility from being incomplete or different to the original definition?\n+\n+Making something accessible can be nuanced and complex and [not all accessibility testing can be automated](https://blog.vararu.org/accessibility-testing-tools-are-lying-to-you/). There are always manual steps needed to test features in the way they impact users.\n+\n+Outlining accessibility issues in criteria records the decisions that were made and define the rules that keep something accessible.\n+\n+In code we can use these criteria to write unit tests that prevent regressions. In our translation component we can test that links have a `lang` attribute, and in our banner component we can [test the contrast ratio](https://github.com/alphagov/govuk_frontend_toolkit/pull/374).\n+\n+## Writing accessibility acceptance criteria\n+\n+### Start with accessibility needs\n+\n+Identify where there is a high risk of introducing an accessibility barrier and include criteria that prevent them.\n+\n+If similar things already exist, review them to find barriers. Test them with users who have access needs. The original criteria for the accessible autocomplete were derived from tests made by Theodor Vararu on existing autocomplete libraries.\n+\n+For many patterns the hard work of defining what accessible means has been documented in guidelines like WCAG. Do the hard work to extract rules specific to what you’re building and link back to the guidelines to give context. Consider which rules are most easily broken and give them prominence.\n+\n+### Don't be too generic\n+\n+Criteria are useful if they are specific and testable.\n+\n+When we began writing accessibility acceptance criteria for components we had difficulty knowing what to include. Consider a component that contains links – do the criteria need to list everything that make a link accessible? How much of this becomes a reproduction of existing guidelines?\n+\n+In this case it was helpful to create a shared definition of an accessible link that could be linked to. This avoided diluting the criteria while giving us a place to record more generic decisions.\n+\n+### Iterate criteria\n+\n+As something is built and tested, continue to refine your criteria as you find missing needs. When accessibility bugs are found – a browser bug, a screen reader quirk, new technology misbehaving, add further criteria and treat them like a failing unit test.\n+\n+### Separate guidance and accessibility acceptance criteria\n+\n+Guidance is for users, accessibility acceptance criteria are for maintainers.\n+\n+Not everything is under your control. For instance, some of our components may become inaccessible if they’re passed certain parameters. Consider a contrived example of the translation component being passed data that says a link is in English but on inspection actually reads in Arabic.","path":"source/_posts/accessibility-acceptance-criteria.md","position":112,"original_position":112,"commit_id":"4d4dc62fdad1e7ec8a05e978be193e6b987297b6","original_commit_id":"4d4dc62fdad1e7ec8a05e978be193e6b987297b6","user":{"login":"edwardhorsford","id":2204224,"avatar_url":"https://avatars3.githubusercontent.com/u/2204224?v=4","gravatar_id":"","url":"https://api.github.com/users/edwardhorsford","html_url":"https://github.com/edwardhorsford","followers_url":"https://api.github.com/users/edwardhorsford/followers","following_url":"https://api.github.com/users/edwardhorsford/following{/other_user}","gists_url":"https://api.github.com/users/edwardhorsford/gists{/gist_id}","starred_url":"https://api.github.com/users/edwardhorsford/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edwardhorsford/subscriptions","organizations_url":"https://api.github.com/users/edwardhorsford/orgs","repos_url":"https://api.github.com/users/edwardhorsford/repos","events_url":"https://api.github.com/users/edwardhorsford/events{/privacy}","received_events_url":"https://api.github.com/users/edwardhorsford/received_events","type":"User","site_admin":false},"body":"I'm not sure what this paragraph is trying to say.","created_at":"2017-08-23T11:43:09Z","updated_at":"2017-08-23T11:53:22Z","html_url":"https://github.com/fofr/paulrhayes.com/pull/19#discussion_r134727357","pull_request_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19","_links":{"self":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/comments/134727357"},"html":{"href":"https://github.com/fofr/paulrhayes.com/pull/19#discussion_r134727357"},"pull_request":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19"}}},"pull_request":{"url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19","id":136252710,"html_url":"https://github.com/fofr/paulrhayes.com/pull/19","diff_url":"https://github.com/fofr/paulrhayes.com/pull/19.diff","patch_url":"https://github.com/fofr/paulrhayes.com/pull/19.patch","issue_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/19","number":19,"state":"open","locked":false,"title":"Write accessibility acceptance criteria blog post","user":{"login":"fofr","id":319055,"avatar_url":"https://avatars3.githubusercontent.com/u/319055?v=4","gravatar_id":"","url":"https://api.github.com/users/fofr","html_url":"https://github.com/fofr","followers_url":"https://api.github.com/users/fofr/followers","following_url":"https://api.github.com/users/fofr/following{/other_user}","gists_url":"https://api.github.com/users/fofr/gists{/gist_id}","starred_url":"https://api.github.com/users/fofr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fofr/subscriptions","organizations_url":"https://api.github.com/users/fofr/orgs","repos_url":"https://api.github.com/users/fofr/repos","events_url":"https://api.github.com/users/fofr/events{/privacy}","received_events_url":"https://api.github.com/users/fofr/received_events","type":"User","site_admin":false},"body":"Part of https://trello.com/c/gqUU1NuF/62-2-blog-about-the-amazing-work-we-are-doing","created_at":"2017-08-17T13:09:21Z","updated_at":"2017-08-23T11:53:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b08a42640c67ff0daa6d16b1e70cae6bcbc0d5ee","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19/commits","review_comments_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19/comments","review_comment_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/comments{/number}","comments_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/19/comments","statuses_url":"https://api.github.com/repos/fofr/paulrhayes.com/statuses/4d4dc62fdad1e7ec8a05e978be193e6b987297b6","head":{"label":"fofr:aac","ref":"aac","sha":"4d4dc62fdad1e7ec8a05e978be193e6b987297b6","user":{"login":"fofr","id":319055,"avatar_url":"https://avatars3.githubusercontent.com/u/319055?v=4","gravatar_id":"","url":"https://api.github.com/users/fofr","html_url":"https://github.com/fofr","followers_url":"https://api.github.com/users/fofr/followers","following_url":"https://api.github.com/users/fofr/following{/other_user}","gists_url":"https://api.github.com/users/fofr/gists{/gist_id}","starred_url":"https://api.github.com/users/fofr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fofr/subscriptions","organizations_url":"https://api.github.com/users/fofr/orgs","repos_url":"https://api.github.com/users/fofr/repos","events_url":"https://api.github.com/users/fofr/events{/privacy}","received_events_url":"https://api.github.com/users/fofr/received_events","type":"User","site_admin":false},"repo":{"id":20195443,"name":"paulrhayes.com","full_name":"fofr/paulrhayes.com","owner":{"login":"fofr","id":319055,"avatar_url":"https://avatars3.githubusercontent.com/u/319055?v=4","gravatar_id":"","url":"https://api.github.com/users/fofr","html_url":"https://github.com/fofr","followers_url":"https://api.github.com/users/fofr/followers","following_url":"https://api.github.com/users/fofr/following{/other_user}","gists_url":"https://api.github.com/users/fofr/gists{/gist_id}","starred_url":"https://api.github.com/users/fofr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fofr/subscriptions","organizations_url":"https://api.github.com/users/fofr/orgs","repos_url":"https://api.github.com/users/fofr/repos","events_url":"https://api.github.com/users/fofr/events{/privacy}","received_events_url":"https://api.github.com/users/fofr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fofr/paulrhayes.com","description":"Articles in markdown format, website theme, styles and script","fork":false,"url":"https://api.github.com/repos/fofr/paulrhayes.com","forks_url":"https://api.github.com/repos/fofr/paulrhayes.com/forks","keys_url":"https://api.github.com/repos/fofr/paulrhayes.com/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fofr/paulrhayes.com/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fofr/paulrhayes.com/teams","hooks_url":"https://api.github.com/repos/fofr/paulrhayes.com/hooks","issue_events_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/events{/number}","events_url":"https://api.github.com/repos/fofr/paulrhayes.com/events","assignees_url":"https://api.github.com/repos/fofr/paulrhayes.com/assignees{/user}","branches_url":"https://api.github.com/repos/fofr/paulrhayes.com/branches{/branch}","tags_url":"https://api.github.com/repos/fofr/paulrhayes.com/tags","blobs_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/refs{/sha}","trees_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fofr/paulrhayes.com/statuses/{sha}","languages_url":"https://api.github.com/repos/fofr/paulrhayes.com/languages","stargazers_url":"https://api.github.com/repos/fofr/paulrhayes.com/stargazers","contributors_url":"https://api.github.com/repos/fofr/paulrhayes.com/contributors","subscribers_url":"https://api.github.com/repos/fofr/paulrhayes.com/subscribers","subscription_url":"https://api.github.com/repos/fofr/paulrhayes.com/subscription","commits_url":"https://api.github.com/repos/fofr/paulrhayes.com/commits{/sha}","git_commits_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/commits{/sha}","comments_url":"https://api.github.com/repos/fofr/paulrhayes.com/comments{/number}","issue_comment_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/comments{/number}","contents_url":"https://api.github.com/repos/fofr/paulrhayes.com/contents/{+path}","compare_url":"https://api.github.com/repos/fofr/paulrhayes.com/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fofr/paulrhayes.com/merges","archive_url":"https://api.github.com/repos/fofr/paulrhayes.com/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fofr/paulrhayes.com/downloads","issues_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues{/number}","pulls_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls{/number}","milestones_url":"https://api.github.com/repos/fofr/paulrhayes.com/milestones{/number}","notifications_url":"https://api.github.com/repos/fofr/paulrhayes.com/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fofr/paulrhayes.com/labels{/name}","releases_url":"https://api.github.com/repos/fofr/paulrhayes.com/releases{/id}","deployments_url":"https://api.github.com/repos/fofr/paulrhayes.com/deployments","created_at":"2014-05-26T18:55:41Z","updated_at":"2017-03-17T14:30:15Z","pushed_at":"2017-08-17T13:16:42Z","git_url":"git://github.com/fofr/paulrhayes.com.git","ssh_url":"git@github.com:fofr/paulrhayes.com.git","clone_url":"https://github.com/fofr/paulrhayes.com.git","svn_url":"https://github.com/fofr/paulrhayes.com","homepage":"http://www.paulrhayes.com","size":26088,"stargazers_count":20,"watchers_count":20,"language":"CSS","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":30,"mirror_url":null,"open_issues_count":1,"forks":30,"open_issues":1,"watchers":20,"default_branch":"master"}},"base":{"label":"fofr:master","ref":"master","sha":"2c6a1e3259b602873a81ea0245fcbe1c40f20cd5","user":{"login":"fofr","id":319055,"avatar_url":"https://avatars3.githubusercontent.com/u/319055?v=4","gravatar_id":"","url":"https://api.github.com/users/fofr","html_url":"https://github.com/fofr","followers_url":"https://api.github.com/users/fofr/followers","following_url":"https://api.github.com/users/fofr/following{/other_user}","gists_url":"https://api.github.com/users/fofr/gists{/gist_id}","starred_url":"https://api.github.com/users/fofr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fofr/subscriptions","organizations_url":"https://api.github.com/users/fofr/orgs","repos_url":"https://api.github.com/users/fofr/repos","events_url":"https://api.github.com/users/fofr/events{/privacy}","received_events_url":"https://api.github.com/users/fofr/received_events","type":"User","site_admin":false},"repo":{"id":20195443,"name":"paulrhayes.com","full_name":"fofr/paulrhayes.com","owner":{"login":"fofr","id":319055,"avatar_url":"https://avatars3.githubusercontent.com/u/319055?v=4","gravatar_id":"","url":"https://api.github.com/users/fofr","html_url":"https://github.com/fofr","followers_url":"https://api.github.com/users/fofr/followers","following_url":"https://api.github.com/users/fofr/following{/other_user}","gists_url":"https://api.github.com/users/fofr/gists{/gist_id}","starred_url":"https://api.github.com/users/fofr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fofr/subscriptions","organizations_url":"https://api.github.com/users/fofr/orgs","repos_url":"https://api.github.com/users/fofr/repos","events_url":"https://api.github.com/users/fofr/events{/privacy}","received_events_url":"https://api.github.com/users/fofr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fofr/paulrhayes.com","description":"Articles in markdown format, website theme, styles and script","fork":false,"url":"https://api.github.com/repos/fofr/paulrhayes.com","forks_url":"https://api.github.com/repos/fofr/paulrhayes.com/forks","keys_url":"https://api.github.com/repos/fofr/paulrhayes.com/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fofr/paulrhayes.com/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fofr/paulrhayes.com/teams","hooks_url":"https://api.github.com/repos/fofr/paulrhayes.com/hooks","issue_events_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/events{/number}","events_url":"https://api.github.com/repos/fofr/paulrhayes.com/events","assignees_url":"https://api.github.com/repos/fofr/paulrhayes.com/assignees{/user}","branches_url":"https://api.github.com/repos/fofr/paulrhayes.com/branches{/branch}","tags_url":"https://api.github.com/repos/fofr/paulrhayes.com/tags","blobs_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/refs{/sha}","trees_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fofr/paulrhayes.com/statuses/{sha}","languages_url":"https://api.github.com/repos/fofr/paulrhayes.com/languages","stargazers_url":"https://api.github.com/repos/fofr/paulrhayes.com/stargazers","contributors_url":"https://api.github.com/repos/fofr/paulrhayes.com/contributors","subscribers_url":"https://api.github.com/repos/fofr/paulrhayes.com/subscribers","subscription_url":"https://api.github.com/repos/fofr/paulrhayes.com/subscription","commits_url":"https://api.github.com/repos/fofr/paulrhayes.com/commits{/sha}","git_commits_url":"https://api.github.com/repos/fofr/paulrhayes.com/git/commits{/sha}","comments_url":"https://api.github.com/repos/fofr/paulrhayes.com/comments{/number}","issue_comment_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues/comments{/number}","contents_url":"https://api.github.com/repos/fofr/paulrhayes.com/contents/{+path}","compare_url":"https://api.github.com/repos/fofr/paulrhayes.com/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fofr/paulrhayes.com/merges","archive_url":"https://api.github.com/repos/fofr/paulrhayes.com/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fofr/paulrhayes.com/downloads","issues_url":"https://api.github.com/repos/fofr/paulrhayes.com/issues{/number}","pulls_url":"https://api.github.com/repos/fofr/paulrhayes.com/pulls{/number}","milestones_url":"https://api.github.com/repos/fofr/paulrhayes.com/milestones{/number}","notifications_url":"https://api.github.com/repos/fofr/paulrhayes.com/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fofr/paulrhayes.com/labels{/name}","releases_url":"https://api.github.com/repos/fofr/paulrhayes.com/releases{/id}","deployments_url":"https://api.github.com/repos/fofr/paulrhayes.com/deployments","created_at":"2014-05-26T18:55:41Z","updated_at":"2017-03-17T14:30:15Z","pushed_at":"2017-08-17T13:16:42Z","git_url":"git://github.com/fofr/paulrhayes.com.git","ssh_url":"git@github.com:fofr/paulrhayes.com.git","clone_url":"https://github.com/fofr/paulrhayes.com.git","svn_url":"https://github.com/fofr/paulrhayes.com","homepage":"http://www.paulrhayes.com","size":26088,"stargazers_count":20,"watchers_count":20,"language":"CSS","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":30,"mirror_url":null,"open_issues_count":1,"forks":30,"open_issues":1,"watchers":20,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19"},"html":{"href":"https://github.com/fofr/paulrhayes.com/pull/19"},"issue":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/issues/19"},"comments":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/issues/19/comments"},"review_comments":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19/comments"},"review_comment":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/pulls/19/commits"},"statuses":{"href":"https://api.github.com/repos/fofr/paulrhayes.com/statuses/4d4dc62fdad1e7ec8a05e978be193e6b987297b6"}}}}
{"actor":{"display_login":"edwardhorsford"}}