@govtechsg/oobee 0.10.76 → 0.10.78-alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +8 -1
- package/INTEGRATION.md +50 -3
- package/dist/cli.js +252 -0
- package/dist/combine.js +221 -0
- package/dist/constants/cliFunctions.js +306 -0
- package/dist/constants/common.js +1669 -0
- package/dist/constants/constants.js +913 -0
- package/dist/constants/errorMeta.json +319 -0
- package/dist/constants/itemTypeDescription.js +7 -0
- package/dist/constants/oobeeAi.js +121 -0
- package/dist/constants/questions.js +151 -0
- package/dist/constants/sampleData.js +176 -0
- package/dist/crawlers/commonCrawlerFunc.js +428 -0
- package/dist/crawlers/crawlDomain.js +613 -0
- package/dist/crawlers/crawlIntelligentSitemap.js +135 -0
- package/dist/crawlers/crawlLocalFile.js +151 -0
- package/dist/crawlers/crawlSitemap.js +303 -0
- package/dist/crawlers/custom/escapeCssSelector.js +10 -0
- package/dist/crawlers/custom/evaluateAltText.js +11 -0
- package/dist/crawlers/custom/extractAndGradeText.js +44 -0
- package/dist/crawlers/custom/extractText.js +27 -0
- package/dist/crawlers/custom/findElementByCssSelector.js +36 -0
- package/dist/crawlers/custom/flagUnlabelledClickableElements.js +963 -0
- package/dist/crawlers/custom/framesCheck.js +37 -0
- package/dist/crawlers/custom/getAxeConfiguration.js +111 -0
- package/dist/crawlers/custom/gradeReadability.js +23 -0
- package/dist/crawlers/custom/utils.js +1024 -0
- package/dist/crawlers/custom/xPathToCss.js +147 -0
- package/dist/crawlers/guards/urlGuard.js +71 -0
- package/dist/crawlers/pdfScanFunc.js +276 -0
- package/dist/crawlers/runCustom.js +89 -0
- package/dist/exclusions.txt +7 -0
- package/dist/generateHtmlReport.js +144 -0
- package/dist/index.js +62 -0
- package/dist/logs.js +84 -0
- package/dist/mergeAxeResults.js +1588 -0
- package/dist/npmIndex.js +640 -0
- package/dist/proxyService.js +360 -0
- package/dist/runGenerateJustHtmlReport.js +16 -0
- package/dist/screenshotFunc/htmlScreenshotFunc.js +355 -0
- package/dist/screenshotFunc/pdfScreenshotFunc.js +645 -0
- package/dist/services/s3Uploader.js +127 -0
- package/dist/static/ejs/partials/components/allIssues/AllIssues.ejs +9 -0
- package/dist/static/ejs/partials/components/allIssues/CategoryBadges.ejs +82 -0
- package/dist/static/ejs/partials/components/allIssues/FilterBar.ejs +33 -0
- package/dist/static/ejs/partials/components/allIssues/IssuesTable.ejs +41 -0
- package/dist/static/ejs/partials/components/header/SiteInfo.ejs +119 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/AboutScanModal.ejs +15 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/ScanConfiguration.ejs +44 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/ScanDetails.ejs +142 -0
- package/dist/static/ejs/partials/components/prioritiseIssues/IssueDetailCard.ejs +36 -0
- package/dist/static/ejs/partials/components/prioritiseIssues/PrioritiseIssues.ejs +47 -0
- package/dist/static/ejs/partials/components/ruleModal/ruleOffcanvas.ejs +196 -0
- package/dist/static/ejs/partials/components/scannedPagesSegmentedTabs.ejs +48 -0
- package/dist/static/ejs/partials/components/screenshotLightbox.ejs +13 -0
- package/dist/static/ejs/partials/components/shared/InfoAlert.ejs +3 -0
- package/dist/static/ejs/partials/components/summaryScanAbout.ejs +141 -0
- package/dist/static/ejs/partials/components/summaryScanResults.ejs +16 -0
- package/dist/static/ejs/partials/components/summaryTable.ejs +20 -0
- package/dist/static/ejs/partials/components/summaryWcagCompliance.ejs +94 -0
- package/dist/static/ejs/partials/components/topTen.ejs +6 -0
- package/dist/static/ejs/partials/components/wcagCompliance/FailedCriteria.ejs +47 -0
- package/dist/static/ejs/partials/components/wcagCompliance/WcagCompliance.ejs +16 -0
- package/dist/static/ejs/partials/components/wcagCompliance/WcagGaugeBar.ejs +16 -0
- package/dist/static/ejs/partials/components/wcagCoverageDetails.ejs +18 -0
- package/dist/static/ejs/partials/footer.ejs +24 -0
- package/dist/static/ejs/partials/header.ejs +14 -0
- package/dist/static/ejs/partials/main.ejs +29 -0
- package/dist/static/ejs/partials/scripts/allIssues/AllIssues.ejs +376 -0
- package/dist/static/ejs/partials/scripts/bootstrap.ejs +8 -0
- package/dist/static/ejs/partials/scripts/categorySummary.ejs +141 -0
- package/dist/static/ejs/partials/scripts/decodeUnzipParse.ejs +3 -0
- package/dist/static/ejs/partials/scripts/header/SiteInfo.ejs +44 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/AboutScanModal.ejs +51 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/ScanConfiguration.ejs +127 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/ScanDetails.ejs +60 -0
- package/dist/static/ejs/partials/scripts/highlightjs.ejs +335 -0
- package/dist/static/ejs/partials/scripts/popper.ejs +7 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/IssueDetailCard.ejs +137 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/PrioritiseIssues.ejs +214 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/wcagSvgMap.ejs +861 -0
- package/dist/static/ejs/partials/scripts/ruleModal/constants.ejs +957 -0
- package/dist/static/ejs/partials/scripts/ruleModal/itemCardRenderer.ejs +353 -0
- package/dist/static/ejs/partials/scripts/ruleModal/pageAccordionBuilder.ejs +468 -0
- package/dist/static/ejs/partials/scripts/ruleModal/ruleOffcanvas.ejs +306 -0
- package/dist/static/ejs/partials/scripts/ruleModal/utilities.ejs +483 -0
- package/dist/static/ejs/partials/scripts/scannedPagesSegmentedTabs.ejs +35 -0
- package/dist/static/ejs/partials/scripts/screenshotLightbox.ejs +75 -0
- package/dist/static/ejs/partials/scripts/summaryScanResults.ejs +14 -0
- package/dist/static/ejs/partials/scripts/summaryTable.ejs +78 -0
- package/dist/static/ejs/partials/scripts/topTen.ejs +61 -0
- package/dist/static/ejs/partials/scripts/utils.ejs +453 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance/FailedCriteria.ejs +103 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance/WcagGaugeBar.ejs +47 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance.ejs +15 -0
- package/dist/static/ejs/partials/scripts/wcagCoverageDetails.ejs +75 -0
- package/dist/static/ejs/partials/styles/allIssues/AllIssues.ejs +384 -0
- package/dist/static/ejs/partials/styles/bootstrap.ejs +12391 -0
- package/dist/static/ejs/partials/styles/header/SiteInfo.ejs +121 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/AboutScanModal.ejs +82 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/ScanConfiguration.ejs +50 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/ScanDetails.ejs +149 -0
- package/dist/static/ejs/partials/styles/header.ejs +7 -0
- package/dist/static/ejs/partials/styles/highlightjs.ejs +54 -0
- package/dist/static/ejs/partials/styles/prioritiseIssues/IssueDetailCard.ejs +141 -0
- package/dist/static/ejs/partials/styles/prioritiseIssues/PrioritiseIssues.ejs +204 -0
- package/dist/static/ejs/partials/styles/ruleModal/ruleOffcanvas.ejs +456 -0
- package/dist/static/ejs/partials/styles/scannedPagesSegmentedTabs.ejs +46 -0
- package/dist/static/ejs/partials/styles/shared/InfoAlert.ejs +12 -0
- package/dist/static/ejs/partials/styles/styles.ejs +1607 -0
- package/dist/static/ejs/partials/styles/summaryBootstrap.ejs +12458 -0
- package/dist/static/ejs/partials/styles/topTenCard.ejs +44 -0
- package/dist/static/ejs/partials/styles/wcagCompliance/FailedCriteria.ejs +59 -0
- package/dist/static/ejs/partials/styles/wcagCompliance/WcagGaugeBar.ejs +62 -0
- package/dist/static/ejs/partials/styles/wcagCompliance.ejs +36 -0
- package/dist/static/ejs/partials/styles/wcagCoverageDetails.ejs +33 -0
- package/dist/static/ejs/partials/summaryHeader.ejs +70 -0
- package/dist/static/ejs/partials/summaryMain.ejs +49 -0
- package/dist/static/ejs/report.ejs +226 -0
- package/dist/static/ejs/summary.ejs +47 -0
- package/dist/types/types.js +1 -0
- package/dist/utils.js +1070 -0
- package/examples/oobee-cypress-integration-js/cypress/support/e2e.js +36 -6
- package/examples/oobee-cypress-integration-js/cypress.config.js +45 -1
- package/examples/oobee-cypress-integration-ts/cypress.config.ts +47 -1
- package/examples/oobee-cypress-integration-ts/src/cypress/support/e2e.ts +36 -6
- package/examples/oobee-playwright-integration-js/oobee-playwright-demo.js +2 -1
- package/examples/oobee-playwright-integration-ts/src/oobee-playwright-demo.ts +2 -1
- package/examples/oobee-scan-html-demo.js +51 -0
- package/examples/oobee-scan-page-demo.js +40 -0
- package/package.json +9 -3
- package/src/constants/common.ts +2 -2
- package/src/constants/constants.ts +3 -1
- package/src/crawlers/crawlDomain.ts +1 -0
- package/src/crawlers/runCustom.ts +0 -1
- package/src/mergeAxeResults.ts +43 -22
- package/src/npmIndex.ts +500 -131
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
const a11yPlaygroundLink = 'https://a11y.tech.gov.sg/?utm_source=oobee';
|
|
3
|
+
|
|
4
|
+
const whyItMatters = {
|
|
5
|
+
accesskeys:
|
|
6
|
+
'<p>\n Specifying a <code>accesskey</code> attribute value for some part of a\n document allows users to quickly activate or move the focus to a specific\n element by pressing the specified key (usually in combination with the\n <code><kbd>alt</kbd></code> key). Duplicating <code>accesskey</code> values\n creates unexpected effects that ultimately make the page less accessible.\n</p>',
|
|
7
|
+
'area-alt':
|
|
8
|
+
'<p>\n Screen readers have no way of translating images into words. It is important\n that all images, including image maps, have <code>alt</code> text values.\n</p>',
|
|
9
|
+
'aria-allowed-attr':
|
|
10
|
+
'<p>\n Using ARIA attributes in roles where they are not allowed can interfere with\n the accessibility of the web page. Using an invalid role-attribute combination\n will, at best, result in no effect on the accessibility of the application\n and, at worst, may trigger behavior that disables accessibility for entire\n portions of an application.\n</p>',
|
|
11
|
+
'aria-command-name':
|
|
12
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="link"</code>, <code>role="button"</code>, or\n <code>role="menuitem"</code> that do not have an accessible name.\n</p>',
|
|
13
|
+
'aria-dialog-name':
|
|
14
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="dialog"</code> or <code>role="alertdialog"</code> that do not have\n an accessible name.\n</p>',
|
|
15
|
+
'aria-hidden-focus':
|
|
16
|
+
'<p>\n Using the <code>aria-hidden="true"</code> attribute on an element removes the\n element and ALL of its child nodes from the accessibility API making it\n completely inaccessible to screen readers and other assistive technologies.\n Aria-hidden may be used with extreme caution to hide visibly rendered content\n from assistive technologies only if the act of hiding this content is intended\n to improve the experience for users of assistive technologies by removing\n redundant or extraneous content. If aria-hidden is used to hide visible\n content from screen readers, the identical or equivalent meaning and\n functionality must be exposed to assistive technologies.\n</p>',
|
|
17
|
+
'aria-input-field-name':
|
|
18
|
+
'<p>\n This new rule ensures every ARIA input field has an accessible name.\n Accessible names must exist for the following input field roles:\n</p>\n<ul>\n <li>combobox</li>\n <li>listbox</li>\n <li>searchbox</li>\n <li>slider</li>\n <li>spinbutton</li>\n <li>textbox</li>\n</ul>',
|
|
19
|
+
'aria-meter-name':
|
|
20
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="meter"</code> that do not have an accessible name.\n</p>',
|
|
21
|
+
'aria-progressbar-name':
|
|
22
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="progressbar"</code> that do not have an accessible name.\n</p>',
|
|
23
|
+
'aria-required-children':
|
|
24
|
+
'<p>\n For each role, WAI-ARIA explicitly defines which child and parent roles are\n allowable and/or required. ARIA <code>role</code>s missing required child\n <code>role</code>s will not be able to perform the accessibility functions\n intended by the developer.\n</p>',
|
|
25
|
+
'aria-required-parent':
|
|
26
|
+
'<p>\n For each role, WAI-ARIA explicitly defines which child and parent roles are\n allowable and/or required. Elements containing ARIA <code>role</code> values\n missing required parent element <code>role</code> values will not enable\n assistive technology to function as intended by the developer.\n</p>',
|
|
27
|
+
'aria-roledescription':
|
|
28
|
+
'<p>\n Inappropriate <code>aria-roledescription</code> attribute values that conflict\n with an element's implied or explicit <code>role</code> value can interfere\n with the accessibility of the web page. A conflicting\n <code>aria-roledescription</code> attribute value may result in no effect on\n the accessibility of the application and may trigger behavior that disables\n accessibility for entire portions of an application.\n</p>',
|
|
29
|
+
'aria-text':
|
|
30
|
+
'<p>\n When a text node is split by markup (e.g.\n <code><h1>Hello <span>World</span></h1></code>)\n VoiceOver will treat it as two separate phrases instead of just one. Adding\n <code>role="text"</code> around the elements solves the problem. However, it\n also overrides the role of the element and all descendants and treats them all\n as text nodes. If one of the descendant elements is also focusable it would\n create an empty tab stop. That is, you could tab to the element but VoiceOver\n would not announce its name, role, or value.\n</p>',
|
|
31
|
+
'aria-toggle-field-name':
|
|
32
|
+
'<p>\n Ensures every element with a semantic role also has an accessible name.\n Semantic roles include:\n</p>\n<ul>\n <li>checkbox</li>\n <li>menu</li>\n <li>menuitemcheckbox</li>\n <li>menuitemradio</li>\n <li>radio</li>\n <li>radiogroup</li>\n <li>switch</li>\n</ul>',
|
|
33
|
+
'aria-tooltip-name':
|
|
34
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="tooltip"</code> that do not have an accessible name.\n</p>',
|
|
35
|
+
'aria-treeitem-name':
|
|
36
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="treeitem"</code> that do not have an accessible name.\n</p>',
|
|
37
|
+
'aria-valid-attr-value':
|
|
38
|
+
'<p>\n ARIA attributes (i.e. starting with <code>aria-</code>) must contain valid\n values. These values must be spelled correctly and correspond to values that\n make sense for a particular attribute to perform the intended accessibility\n function.\n</p>',
|
|
39
|
+
'aria-valid-attr':
|
|
40
|
+
'<p>\n If the developer uses a non-existent or misspelled ARIA attribute, the\n attribute will not be able to perform the accessibility function intended by\n the developer.\n</p>',
|
|
41
|
+
'autocomplete-valid':
|
|
42
|
+
'<p>\n Failure to provide autocomplete values in form fields results in inaccessible\n content. Screen readers do not read identified autocomplete form fields if the\n appropriate autocomplete attribute values are missing. Users cannot correctly\n navigate forms when screen readers cannot provide adequate information to the\n user regarding form field interaction requirements.\n</p>',
|
|
43
|
+
'avoid-inline-spacing':
|
|
44
|
+
'<p>\n Many people with cognitive disabilities have trouble tracking lines of text\n when a block of text is single spaced. Providing spacing between 1.5 to 2\n allows them to start a new line more easily once they have finished the\n previous one.\n</p>',
|
|
45
|
+
blink:
|
|
46
|
+
'<p>\n As the name suggests, <code>blink</code> tags cause content to flash. Though\n you may like the effect, blinking text can be difficult to read, and blinking\n objects (links, buttons, etc.) can be difficult to activate, especially for\n users with imprecise or limited dexterity.\n</p>',
|
|
47
|
+
'definition-list':
|
|
48
|
+
'<p>\n Screen readers have a specific way of announcing definition lists. When such\n lists are not properly marked up, this creates the opportunity for confusing\n or inaccurate screen reader output.\n</p>',
|
|
49
|
+
dlitem:
|
|
50
|
+
'<p>\n A definition list item must be wrapped in parent <code>dl</code> elements,\n otherwise it will be invalid.\n</p>',
|
|
51
|
+
'duplicate-id-active':
|
|
52
|
+
'<p>\n The ID attribute uniquely identifies focusable elements on a page. It does not\n make sense to duplicate an active ID.\n</p>',
|
|
53
|
+
'empty-table-header':
|
|
54
|
+
'<p>\n Table header elements should have visible text that describes the purpose of\n the row or column to both sighted users and screen reader users.\n</p>',
|
|
55
|
+
'frame-focusable-content':
|
|
56
|
+
'<p>\n When a frame has a negative tabindex, the browser is prevented from\n redirecting the focus to the content inside that frame. This causes all its\n content from getting skipped in keyboard navigation, and if the frame is\n scrollable also prevents the focus from reaching any element from which the\n frame can be scrolled with the keyboard.\n</p>',
|
|
57
|
+
'frame-tested':
|
|
58
|
+
'<p>\n Without the axe-core script, it is not possible for the tool to perform\n violation checking on multiple levels of nested iframes.\n</p>',
|
|
59
|
+
'frame-title-unique':
|
|
60
|
+
'<p>\n Screen reader users rely on a frame title to describe the contents of the\n <code>frame</code>. Navigating through frames and iframes can quickly become\n difficult and confusing for users of this technology if the frames are not\n marked with a <code>title</code> attribute.\n</p>',
|
|
61
|
+
'frame-title':
|
|
62
|
+
'<p>\n Screen reader users rely on a frame title to describe the contents of the\n <code>frame</code>. Navigating through <code>frame</code> and\n <code>iframe</code> elements quickly becomes difficult and confusing for users\n of this technology if the markup does not contain a\n <code>title</code> attribute.\n</p>',
|
|
63
|
+
'html-xml-lang-mismatch':
|
|
64
|
+
'<p>\n When configuring a screen reader, users select a default language. If the\n language of a webpage is not specified, the screen reader assumes the default\n language set by the user. Multiple languages are an issue for users who speak\n and access websites in multiple languages. It is essential to specify a\n default language and ensure that it is valid for screen readers to function\n correctly.\n</p>',
|
|
65
|
+
'image-alt':
|
|
66
|
+
'<p>\n Screen readers have no way of translating an image into words that gets read\n to the user, even if the image only consists of text. As a result, it's\n necessary for images to have short, descriptive <code>alt</code> text so\n screen reader users clearly understand the image's contents and purpose.\n</p>',
|
|
67
|
+
'image-redundant-alt':
|
|
68
|
+
'<p>\n It is unnecessary and potentially confusing to have alternative text for a\n link or image to be repeated in text adjacent to the link or image since it\n would be read twice by a screen reader.\n</p>',
|
|
69
|
+
'input-button-name':
|
|
70
|
+
'<p>\n Screen reader users are not able to discern the purpose of an\n <code>input type="button"</code> without an accessible name.\n</p>',
|
|
71
|
+
'input-image-alt':
|
|
72
|
+
'<p>\n An <code><input type="image"></code> button must have\n alternate text, otherwise screen reader users will not know the button's\n purpose. Even if the image contains only text, it still requires alternate\n text, since a screen reader cannot translate images of words into output.\n</p>',
|
|
73
|
+
'landmark-banner-is-top-level':
|
|
74
|
+
'<p>\n If the banner landmark is not the top-level landmark (and is contained within\n another landmark), it does not effectively designate the pre-defined header\n portion of the layout in the design and therefore prevents screen reader users\n from being able to easily find their way around the layout.\n</p>',
|
|
75
|
+
'landmark-complementary-is-top-level':
|
|
76
|
+
'<p>\n Complementary content is ancillary content to the main theme of a document or\n page. Screen reader users have the option to skip over complementary content\n when it appears at the top level of the accessibility API. Embedding an\n <code><aside></code> element in another landmark may disable screen\n reader functionality allowing users to navigate through complementary content.\n</p>',
|
|
77
|
+
'landmark-contentinfo-is-top-level':
|
|
78
|
+
'<p>\n The purpose of the <code>contentinfo</code> landmark can be defeated when\n placed within another landmark, as it can prevent blind screen reader users\n from being able to quickly find and navigate to the appropriate landmark.\n</p>',
|
|
79
|
+
'landmark-main-is-top-level':
|
|
80
|
+
'<p>\n Navigating a web page is far simpler for screen reader users if the content\n splits between some high-level sections. Content outside of these sections is\n difficult to find, and its purpose may be unclear.\n</p>',
|
|
81
|
+
'landmark-no-duplicate-banner':
|
|
82
|
+
'<p>\n Landmarks allow blind users to navigate and find content quickly. Missing\n landmarks require screen reader users to sort through too much extra\n information to find anything.\n</p>',
|
|
83
|
+
'landmark-no-duplicate-contentinfo':
|
|
84
|
+
'<p>\n One of the main purposes of landmarks is to allow blind users to quickly find\n and navigate to the appropriate landmark, so you should keep the total number\n of landmarks relatively low. If you don't, screen reader users will have to\n sort through too much extra information to find what they're looking for.\n</p>',
|
|
85
|
+
'landmark-no-duplicate-main':
|
|
86
|
+
'<p>\n Navigating a web page is far simpler for screen reader users if all of the\n content splits between one or more high-level sections. Content outside of\n these sections is difficult to find, and its purpose may be unclear.\n</p>',
|
|
87
|
+
'landmark-unique':
|
|
88
|
+
'<p>\n <code>landmark-unique</code> is a new best practice rule ensures that\n landmarks have a unique role or accessible name (i.e. role, label, title)\n combination.\n</p>',
|
|
89
|
+
list: '<p>\n Screen readers have a specific way of announcing lists. This feature makes\n lists clearer to understand, but will only work if lists are properly\n structured.\n</p>',
|
|
90
|
+
listitem:
|
|
91
|
+
'<p>\n For a list to be valid, it must have both parent and child elements. Parent\n elements can either be a set of <code>ul</code> tags or a set of\n <code>ol</code> tags. Child elements must be declared inside of these tags\n using the <code>li</code> tag.\n</p>',
|
|
92
|
+
marquee:
|
|
93
|
+
'<p>\n The <code>marquee</code> element creates scrolling text that is difficult to\n read and click on. Beyond that, it can be distracting to viewers, especially\n to those with low vision, cognitive disabilities, or attention deficits.\n</p>',
|
|
94
|
+
'meta-refresh':
|
|
95
|
+
'<p>\n Since users do not expect a page to refresh automatically, such refreshing can\n be disorienting. Refreshing also moves the programmatic focus back to the top\n of the page, away from where the user had it. Such resetting is frustrating\n for users.\n</p>',
|
|
96
|
+
'object-alt':
|
|
97
|
+
'<p>\n Screen readers have no way of translating non-text content into text announced\n to users. Instead, they read out alternative text. For screen reader users to\n obtain the information contained in embedded <code>object</code> elements\n which must contain short, descriptive alternative text.\n</p>',
|
|
98
|
+
'presentation-role-conflict':
|
|
99
|
+
'<p>\n There are certain cases where the semantic role of an element with\n <code>role="none"</code> or <code>role="presentation"</code> does not resolve\n to none or presentation (respectively). When this happens, the element is not\n removed from the accessibility tree (as expected) and screen readers are able\n to interact with it.\n</p>',
|
|
100
|
+
'role-img-alt':
|
|
101
|
+
'<p>\n Screen readers have no way of translating an image into words that gets read\n to the user, even if the image only consists of text. As a result, it's\n necessary for images to have short, descriptive and accessible alternative\n text so screen reader users clearly understand the image's contents and\n purpose.\n</p>',
|
|
102
|
+
'scope-attr-valid':
|
|
103
|
+
'<p>\n The <code>scope</code> attribute makes table navigation much easier for screen\n reader users, provided that it is used correctly. Incorrectly used,\n <code>scope</code> can make table navigation much harder and less efficient.\n</p>',
|
|
104
|
+
'scrollable-region-focusable':
|
|
105
|
+
'<p>\n Checks scrollable content for focusable elements enabling keyboard navigation.\n Keyboard navigation should not fail when focus moves to an element within a\n scrollable region.\n</p>',
|
|
106
|
+
'select-name':
|
|
107
|
+
'<p>\n Effective form labels are required to make forms accessible. The purpose of\n form elements such as checkboxes, radio buttons, input fields, etcetera, is\n often apparent to sighted users, even if the form element is not\n programmatically labeled. Screen readers users require useful form labels to\n identify form fields. Adding a label to all form elements eliminates ambiguity\n and contributes to a more accessible product.\n</p>',
|
|
108
|
+
'server-side-image-map':
|
|
109
|
+
'<p>\n Server-side image maps are not keyboard accessible; mouse clicks are required\n to access the links contained in the image, making the image inaccessible to\n people who only use keyboards for their navigation.\n</p>',
|
|
110
|
+
'skip-link':
|
|
111
|
+
'<p>\n Screen readers announce content sequentially as it appears in the HTML file.\n What this means for users of assistive technology is that the content at the\n top of the page, typically including the entire navigation, is read out to the\n user before reaching any of the main content. Since content at the top of the\n page can often be very lengthy, it can be time-consuming to listen to or tab\n through all of it when the user is only interested in the main content.\n Including a skip link in an HTML page is beneficial to blind users, users with\n low vision, and mouse-only users.\n</p>',
|
|
112
|
+
'svg-img-alt':
|
|
113
|
+
"<p>\n If you can't see, images are completely useless without a digital text alternative. The same is true in varying degrees for people with low vision or colour-blindness. \n</p>",
|
|
114
|
+
tabindex:
|
|
115
|
+
'<p>\n Using <code>tabindex</code> with a value greater than 0 can create as many\n problems as it solves. It creates an unexpected tab order, which makes the\n page less intuitive and can give the appearance of skipping certain elements\n entirely.\n</p>',
|
|
116
|
+
'table-duplicate-name':
|
|
117
|
+
'<p>\n When tables have summary and caption text that is identical, screen reader\n users can be confused and find it difficult to know the name and purpose of\n the table.\n</p>',
|
|
118
|
+
'td-headers-attr':
|
|
119
|
+
"<p>\n Sighted users can usually tell at a glance what the table's headers are and\n what their relationship to the data is. For non-sighted users this must be\n done in the markup.\n</p>",
|
|
120
|
+
'th-has-data-cells':
|
|
121
|
+
'<p>\n When tables are not marked up semantically and do not have the correct header\n structure, screen reader users cannot correctly perceive the relationships\n between the cells and their contents visually.\n</p>',
|
|
122
|
+
'valid-lang':
|
|
123
|
+
'<p>\n When configuring a screen reader, users select a default language. If the\n language of a webpage is not specified, the screen reader assumes it is the\n default language set by the user. Language selection becomes an issue for\n users who speak multiple languages and access the website in more than one\n language. It is essential to specify a language and ensure that it is valid so\n website text is pronounced correctly.\n</p>',
|
|
124
|
+
'video-caption':
|
|
125
|
+
'<p>\n If a video has no caption, deaf users have limited or no access to the\n information contained in it. Even if a captions track is available, ensure\n that it contains all meaningful information in the video, not just dialogue.\n</p>',
|
|
126
|
+
'no-autoplay-audio':
|
|
127
|
+
'<p>\n People who are blind or have low vision and use screen reading software can\n find it hard to hear the screen reader's speech output if there is other audio\n playing at the same time. If automatically playing audio lasts more than three\n seconds, an easily located, accessible mechanism must be provided to pause or\n stop the audio or control the audio volume. An audio control allows screen\n reader users to hear the screen reader without other sounds playing.\n</p>',
|
|
128
|
+
'aria-hidden-body':
|
|
129
|
+
'<p>\n Screen readers do not read content marked with the <code>aria-hidden="true"</code> attribute value. Users can still tab to focusable elements in the hidden objects, but screen readers remain silent.\n</p>',
|
|
130
|
+
'aria-required-attr':
|
|
131
|
+
'<p>\n ARIA widget roles require additional attributes that describe the state of the\n widget. The state of the widget is not communicated to screen reader users if\n a required attribute is omitted.\n</p>',
|
|
132
|
+
bypass:
|
|
133
|
+
'<p>\n Since web sites often display secondary, repeated content on multiple pages\n (such as navigation links, heading graphics, and advertising frames),\n keyboard-only users benefit from faster, more direct access to the primary\n content on a page. This reduces keystrokes and minimizes associated physical\n pain.\n</p>',
|
|
134
|
+
'color-contrast':
|
|
135
|
+
'<p>\n Some people with low vision experience low contrast, meaning that there aren't\n very many bright or dark areas. Everything tends to appear about the same\n brightness, which makes it hard to distinguish outlines, borders, edges, and\n details. Text that is too close in luminance (brightness) to the background\n can be hard to read.\n</p>',
|
|
136
|
+
'document-title':
|
|
137
|
+
'<p>\n Screen reader users use page titles to get an overview of the contents of the\n page. Navigating through pages can quickly become difficult and confusing for\n screen reader users if the pages are not marked with a title. The page\n <code>title</code> element is the first thing screen reader users hear when\n first loading a web page.\n</p>',
|
|
138
|
+
'duplicate-id-aria':
|
|
139
|
+
'<p>\n Duplicate IDs are common validation errors that may break the accessibility of\n labels, e.g., ARIA elements, form fields, table header cells.\n</p>',
|
|
140
|
+
'duplicate-id':
|
|
141
|
+
"<p>\n The ID attribute uniquely identifies elements on a page. It does not make\n sense to duplicate an ID.\n</p>\n\n<p>\n Duplicate ID's can break the accessibility of labels for forms, table header\n cells, etc., by the second instance being skipped by screen readers, or by\n client-side scripts. They are common markup validation errors that can\n eliminate possible sources of accessibility problems, when not breaking\n accessibility.\n</p>",
|
|
142
|
+
'empty-heading':
|
|
143
|
+
'<p>\n Screen readers alert users to the presence of a heading tag. If the heading is\n empty or the text cannot be accessed, this could either confuse users or even\n prevent them from accessing information on the page's structure.\n</p>',
|
|
144
|
+
'form-field-multiple-labels':
|
|
145
|
+
'<p>\n Assigning multiple labels to the same form field can cause problems for some\n combinations of screen readers and browsers, and the results are inconsistent\n from one combination to the next. Some combinations will read the first label.\n Some will read the last label. Others will read both labels.\n</p>',
|
|
146
|
+
'heading-order':
|
|
147
|
+
'<p>\n The underlying purpose of headers is to convey the structure of the page. For\n sighted users, the same purpose is achieved using different sizes of text.\n Text size, however, is not helpful for users of screen readers, because a\n screen reader identifies a header only if it is properly marked-up. When\n heading elements are applied correctly, the page becomes much easier to\n navigate for screen reader users and sighted users alike.\n</p>',
|
|
148
|
+
'html-has-lang':
|
|
149
|
+
'<p>\n When configuring a screen reader, users select a default language. If the\n language of a webpage is not specified, the screen reader assumes the default\n language set by the user. Language settings become an issue for users who\n speak multiple languages and access website in more than one language. It is\n essential to specify a language and ensure that it is valid so website text is\n pronounced correctly.\n</p>',
|
|
150
|
+
'html-lang-valid':
|
|
151
|
+
'<p>\n When configuring a screen reader, users select a default language. If the\n language of a webpage is not specified, the screen reader assumes the default\n language set by the user. Language settings are an issue for users who speak\n multiple languages and access website in more than one language. It is\n essential to specify a language and ensure that it is valid so website text is\n pronounced correctly.\n</p>',
|
|
152
|
+
'label-title-only':
|
|
153
|
+
'<p>\n The <code>title</code> and <code>aria-describedby</code> attributes are used\n to provide additional information such as a hint. Hints are exposed to\n accessibility APIs differently than labels and as such, this can cause\n problems with assistive technologies.\n</p>',
|
|
154
|
+
'link-in-text-block':
|
|
155
|
+
'<p>\n Some people with low vision experience low contrast, meaning that there aren't\n very many bright or dark areas. Everything tends to appear about the same\n brightness, which makes it hard to distinguish outlines, borders, edges, and\n details. Text that is too close in luminance (brightness) to the background\n can be hard to read.\n</p>',
|
|
156
|
+
'link-name':
|
|
157
|
+
'<p>\n Inaccessible link elements pose barriers to accessibility, as they are a fundamental component of a website.\n </p>',
|
|
158
|
+
'meta-viewport-large':
|
|
159
|
+
'<p>\n The <code>user-scalable="no"</code> parameter inside the\n <code>content</code> attribute of\n <code><meta name="viewport"></code> element disables zooming on a page.\n The <code>maximum-scale</code> parameter limits the amount the user can zoom.\n This is problematic for people with low vision who rely on screen magnifiers\n to properly see the contents of a web page.\n</p>',
|
|
160
|
+
'meta-viewport':
|
|
161
|
+
'<p>\n The <code>user-scalable="no"</code> parameter inside the\n <code>content</code> attribute of\n <code><meta name="viewport"></code> element disables zooming on a page.\n The <code>maximum-scale</code> parameter limits the amount the user can zoom.\n This is problematic for people with low vision who rely on screen magnifiers\n to properly see the contents of a web page.\n</p>',
|
|
162
|
+
'nested-interactive':
|
|
163
|
+
'<p>\n Focusable elements with an interactive control ancestor (any element that\n accepts user input such as button or anchor elements) are not announced by\n screen readers and create an empty tab stop. That is, you could tab to the\n element but the screen reader will not announce its name, role, or state.\n</p>',
|
|
164
|
+
'page-has-heading-one':
|
|
165
|
+
'<p>\n Screen reader users can use keyboard shortcuts to navigate directly to the\n first <code>h1</code>, which, in principle, should allow them to jump directly\n to the main content of the web page. If there is no <code>h1</code>, or if the\n <code>h1</code> appears somewhere other than at the start of the main content,\n screen reader users must listen to more of the web page to understand its\n structure, wasting valuable time.\n</p>',
|
|
166
|
+
region:
|
|
167
|
+
'<p>\n Navigating a web page is far simpler for screen reader users if the content\n splits between multiple high-level sections. Content outside of sections is\n difficult to find, and the content's purpose may be unclear.\n</p>',
|
|
168
|
+
'button-name':
|
|
169
|
+
'<p>\n Screen reader users are not able to discern the purpose of elements with\n <code>role="link"</code>, <code>role="button"</code>, or\n <code>role="menuitem"</code> that do not have an accessible name.\n</p>',
|
|
170
|
+
'aria-allowed-role':
|
|
171
|
+
'<p>\n Intended accessible technology behavior by a developer is not enabled when an\n assigned WAI-ARIA role value is invalid for the parent element.\n</p>',
|
|
172
|
+
'aria-roles':
|
|
173
|
+
'<p>\n Elements assigned invalid ARIA role values are not interpreted by assistive\n technology as intended by the developer.\n</p>',
|
|
174
|
+
label:
|
|
175
|
+
'<p>\n Effective form labels are required to make forms accessible. The purpose of\n form elements such as checkboxes, radio buttons, input fields, etcetera, is\n often apparent to sighted users, even if the form element is not\n programmatically labeled. Screen readers users require useful form labels to\n identify form fields. Adding a label to all form elements eliminates ambiguity\n and contributes to a more accessible product.\n</p>',
|
|
176
|
+
'landmark-one-main':
|
|
177
|
+
'<p>\n Navigating a web page is far simpler for screen reader users if all of the\n content splits between one or more high-level sections. Content outside of\n these sections is difficult to find, and its purpose may be unclear.\n</p>',
|
|
178
|
+
'aria-braille-equivalent':
|
|
179
|
+
'<p class="rule-desc-text">\nARIA braille attributes were introduced to allow adjusting how labels and role descriptions are rendered on a braille display. They cannot be the only attribute providing a label, or a role description. When used without a corresponding label or role description ARIA says to ignore these attributes, although this may not happen consistently in screen readers and other assistive technologies.\n</p>',
|
|
180
|
+
'aria-conditional-attr':
|
|
181
|
+
'<p class="rule-desc-text">\nUsing ARIA attributes on elements where they are not expected can result in unpredictable behavior for assistive technologies. This can lead to a poor user experience for people with disabilities who rely on these technologies. It is important to follow the ARIA specification to ensure that assistive technologies can properly interpret and communicate the intended meaning of the content.\n</p>',
|
|
182
|
+
'aria-deprecated-role':
|
|
183
|
+
'<p class="rule-desc-text">\nUsing deprecated WAI-ARIA roles is bad for accessibility. They will not be recognized or correctly processed by screen readers and other assistive technologies. Using these means not everyone will be able to access essential information.\n</p>',
|
|
184
|
+
'aria-prohibited-attr':
|
|
185
|
+
'<p class="rule-desc-text">\nUsing ARIA attributes in roles where they are prohibited can mean that important information is not communicated to users of assistive technologies. assistive technologies may also attempt to compensate for the issue, resulting in inconsistent and confusing behavior of these tools.\n</p>',
|
|
186
|
+
'target-size':
|
|
187
|
+
'<p>\n Touch targets must have sufficient size and spacing in order to "be easily activated without accidentally activating an adjacent target." When touch targets are too small or too close together, it becomes difficult for users to activate them.\n</p>',
|
|
188
|
+
'oobee-confusing-alt-text':
|
|
189
|
+
'<p>\n Alt text should be clear and concise. It should relay informative content / function of the image. If the alt text is too long or confusing, it can be difficult for screen reader users to understand the image.\n</p>',
|
|
190
|
+
'oobee-accessible-label':
|
|
191
|
+
'<p>\n Unlabelled clickable elements are inaccessible because it prevents screen readers from effectively conveying the purpose of the element. This causes challenges for screen reader users to navigate and understand the webpage. Clickable elements should also be made focusable by screen readers unless deliberately excluded (e.g. decorative or functionally redundant).\n</p>',
|
|
192
|
+
'oobee-grading-text-contents':
|
|
193
|
+
'<p>\n Text content should be easy to understand for individuals with education levels up to university graduates. If the text content is difficult to understand, provide supplemental content or a version that is easy to understand.\n</p>',
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const stepByStepGuide = {
|
|
197
|
+
'aria-meter-name': {
|
|
198
|
+
check:
|
|
199
|
+
'Find visual progress or measurement indicators (like storage capacity bars or battery level indicators, volume controls)',
|
|
200
|
+
fix: '(Developer) Add a text alternative that says what the meter measures (e.g., "Storage used")',
|
|
201
|
+
review: 'Use a screen reader to confirm it announces the measurement and what it refers to',
|
|
202
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
203
|
+
},
|
|
204
|
+
'aria-progressbar-name': {
|
|
205
|
+
check: 'Find progress bars on the page (e.g., file upload, page loading, processing)',
|
|
206
|
+
fix: '(Developer) Add a text alternative that says what\'s in progress (e.g., "File upload")',
|
|
207
|
+
review:
|
|
208
|
+
'Trigger the progress action and confirm the screen reader announces both the label and the current percentage',
|
|
209
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
210
|
+
},
|
|
211
|
+
'image-alt': {
|
|
212
|
+
check:
|
|
213
|
+
'Find images on the page that carry meaning (product photos, charts, diagrams, icons that communicate something important). Skip images that are just decoration, like spacers or background patterns.',
|
|
214
|
+
fix: '(Developer) Add short, specific alt text for each meaningful image. If an image is only decoration, mark it so screen readers skip it.',
|
|
215
|
+
review:
|
|
216
|
+
"Use a screen reader to read each image's description and confirm it adequately explains what the image shows and why it matters.",
|
|
217
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
218
|
+
},
|
|
219
|
+
'input-image-alt': {
|
|
220
|
+
check:
|
|
221
|
+
"Find buttons that use only images or icons like a delete icon, search icon, menu icon, print icon, etc. Look for buttons where you'd only see a picture, not text.",
|
|
222
|
+
fix: '(Developer) Add a clear label to each image button that describes the ACTION, not just the icon. e.g., "Delete".',
|
|
223
|
+
review:
|
|
224
|
+
'Use a screen reader on the button and confirm it announces the action clearly. When you tab to a delete button, the screen reader should say "Delete button" (or similar), not "Trash can image."',
|
|
225
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
226
|
+
},
|
|
227
|
+
'object-alt': {
|
|
228
|
+
check:
|
|
229
|
+
"Find embedded objects on the page: PDFs, videos, interactive tools, maps, or other content that's embedded within the page. These are different from regular images.",
|
|
230
|
+
fix: '(Developer) Add a clear, descriptive label or title for each embedded object. The label should identify what the content is and, if helpful, provide additional context (file type, duration, etc.).',
|
|
231
|
+
review:
|
|
232
|
+
'Use a screen reader to navigate to each embedded object and confirm the screen reader announces: (1) What the object is (PDF, video, map, etc.) (2) What it contains (3) Any relevant additional info (like duration for videos, file size for PDFs).',
|
|
233
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
234
|
+
},
|
|
235
|
+
'oobee-confusing-alt-text': {
|
|
236
|
+
check:
|
|
237
|
+
'Find images that already have descriptions but the descriptions are too vague or unhelpful. Look for descriptions that just say: "image"',
|
|
238
|
+
fix: '(Developer) Rewrite each vague description to actually describe what the image shows.',
|
|
239
|
+
review:
|
|
240
|
+
"Use a screen reader to read the updated descriptions and confirm they now adequately convey what the image shows and its purpose. A person listening should understand the image's content and why it matters.",
|
|
241
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
242
|
+
},
|
|
243
|
+
'role-img-alt': {
|
|
244
|
+
check:
|
|
245
|
+
"Find elements that are marked as images but aren't traditional image elements (like custom icons or graphics).",
|
|
246
|
+
fix: '(Developer) Add a text description that identifies what the element is e.g., "Settings icon"',
|
|
247
|
+
review:
|
|
248
|
+
"Use a screen reader to read each element's description and confirm it adequately conveys what the element represents and its purpose.",
|
|
249
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
250
|
+
},
|
|
251
|
+
'svg-img-alt': {
|
|
252
|
+
check:
|
|
253
|
+
'Find vector graphics (SVG elements) on the page that are marked as images. These might be logos, icons, diagrams, or other graphics',
|
|
254
|
+
fix: '(Developer) Add a text description that identifies what the graphic is. e.g., "Company logo"',
|
|
255
|
+
review:
|
|
256
|
+
"Use a screen reader to read each SVG's description and confirm it adequately conveys what the graphic shows and its purpose",
|
|
257
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
258
|
+
},
|
|
259
|
+
'video-caption': {
|
|
260
|
+
check: 'Identify which videos on the page lack captions',
|
|
261
|
+
fix: '(Developer) Add caption tracks (<track> elements) to those videos with synchronized captions that include dialogue and important sounds',
|
|
262
|
+
review:
|
|
263
|
+
'Play the video muted to confirm captions display, are synchronized with the video, and cover all spoken dialogue and important sounds',
|
|
264
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
265
|
+
},
|
|
266
|
+
'aria-required-children': {
|
|
267
|
+
check: 'Open the reported page and locate the element with the missing child elements',
|
|
268
|
+
fix: "(Developer) Add the required child elements as described in the issue's fix. e.g., if a list role is missing list item children, add them",
|
|
269
|
+
review:
|
|
270
|
+
'Use a screen reader to navigate the control and confirm it is working as expected—the structure is announced correctly and all items/options are accessible',
|
|
271
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
272
|
+
},
|
|
273
|
+
'aria-required-parent': {
|
|
274
|
+
check: 'Open the reported page and locate the element that is missing its required parent',
|
|
275
|
+
fix: "(Developer) Move or nest the element inside its required parent element as described in the issue's fix. e.g., if a tab element is incorrectly placed outside a parent, move it inside a 'tab list' parent",
|
|
276
|
+
review:
|
|
277
|
+
'Use a screen reader to navigate the control and confirm it is working as expected—the relationship between parent and child is announced correctly and the control functions properly.',
|
|
278
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
279
|
+
},
|
|
280
|
+
'definition-list': {
|
|
281
|
+
check: 'Find glossary or FAQ sections where terms are paired with answers or definitions.',
|
|
282
|
+
fix: '(Developer) Ensure the definition list (<dl>) contains only <dt> (term) and <dd> (definition) elements as direct children. Remove any other HTML elements that may be incorrectly placed directly inside the <dl>',
|
|
283
|
+
review:
|
|
284
|
+
'Use a screen reader to navigate the definition list and confirm it correctly announces the term-definition relationships.',
|
|
285
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
286
|
+
},
|
|
287
|
+
dlitem: {
|
|
288
|
+
check:
|
|
289
|
+
'Find any terms or definitions on the page that appear outside a proper glossary structure.',
|
|
290
|
+
fix: '(Developer) Ensure the definition list (<dl>) contains only <dt> (term) and <dd> (definition) elements as direct children. Remove any other HTML elements that may be incorrectly placed directly inside the <dl>',
|
|
291
|
+
review:
|
|
292
|
+
'Use a screen reader to navigate the definition list and confirm it correctly announces the term-definition relationships.',
|
|
293
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
294
|
+
},
|
|
295
|
+
list: {
|
|
296
|
+
check:
|
|
297
|
+
'Find bullet point or numbered lists on the page. Check that each item is wrapped in a list item element and that list items have a list container as their parent. Look for any text appearing directly in the list without being in a list item.',
|
|
298
|
+
fix: '(Developer) Wrap each list item in <li> elements. Ensure <li> elements are direct children of <ul> or <ol>—nothing else should be a direct child.',
|
|
299
|
+
review:
|
|
300
|
+
'Use a screen reader to navigate the list and confirm it announces the list structure and item count correctly.',
|
|
301
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
302
|
+
},
|
|
303
|
+
listitem: {
|
|
304
|
+
check:
|
|
305
|
+
'Find content formatted as list items (usually bullets or numbers). Verify each item is inside a list container. Look for orphaned list items appearing outside any list.',
|
|
306
|
+
fix: '(Developer) Ensure all <li> elements are direct children of a <ul> or <ol> parent. Move any orphaned <li> elements into the correct list container.',
|
|
307
|
+
review:
|
|
308
|
+
'Use a screen reader to navigate and confirm the list announces correctly with proper list structure and item count.',
|
|
309
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
310
|
+
},
|
|
311
|
+
'td-headers-attr': {
|
|
312
|
+
check:
|
|
313
|
+
'Pick a table on the page and use a screen reader to read one row cell-by-cell. As you move through cells, the screen reader should announce the relevant header so you understand what each cell represents.',
|
|
314
|
+
fix: '(Developer) Link headers to cells and add any missing header text that helps identify the meaning of the column or row.',
|
|
315
|
+
review:
|
|
316
|
+
'Use a screen reader to move cell-by-cell through the table and confirm the correct header is announced for each cell.',
|
|
317
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
318
|
+
},
|
|
319
|
+
'th-has-data-cells': {
|
|
320
|
+
check:
|
|
321
|
+
'Pick a table and use a screen reader to read one row cell-by-cell. For each data cell you read, the screen reader should announce the header that applies to it.',
|
|
322
|
+
fix: '(Developer) Ensure headers are properly connected to their data cells. Mark headers correctly as row or column headers. Add any missing header information or remove invalid table headers.',
|
|
323
|
+
review:
|
|
324
|
+
"Use a screen reader to move cell-by-cell through the table and confirm each data cell's correct header is announced.",
|
|
325
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
326
|
+
},
|
|
327
|
+
'autocomplete-valid': {
|
|
328
|
+
check:
|
|
329
|
+
'Find forms that collect common information like names, or emails. Check if fields have autocomplete attributes.',
|
|
330
|
+
fix: '(Developer) Set valid autocomplete attributes on each field. e.g., name → "name", email → "email". Use attributes that match the specification.',
|
|
331
|
+
review:
|
|
332
|
+
"Test browser autofill: Type information into your browser's profile and see if fields autofill correctly with the matching data.",
|
|
333
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
334
|
+
},
|
|
335
|
+
'link-in-text-block': {
|
|
336
|
+
check:
|
|
337
|
+
'Scan text blocks on the page: Can you identify every link without hovering? Look for links that depend only on color to stand out.',
|
|
338
|
+
fix: '(Developer) Add visual distinction beyond color—such as underline, bold, or different font style. Ensure the distinction has good contrast and remains visible.',
|
|
339
|
+
review:
|
|
340
|
+
'Check a sample page: Without hovering over text, do links stand out clearly? Try viewing the page in grayscale to verify links are still distinguishable.',
|
|
341
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
342
|
+
},
|
|
343
|
+
'avoid-inline-spacing': {
|
|
344
|
+
check:
|
|
345
|
+
'Open the page and increase browser text spacing to between 1.5 and 2 times normal (e.g. using a Chrome Extension). Observe: Does the text spacing actually adjust on the page? Can you still read all the content?',
|
|
346
|
+
fix: '(Developer) Check CSS style sheets and ensure they do not contain fixed line-spacing or text spacing values e.g. !important. Allow browser and user settings to control spacing. Ensure the layout remains functional when spacing is increased.',
|
|
347
|
+
review:
|
|
348
|
+
'Confirm that with increased text spacing, no content is cut off and nothing overlaps making it unreadable.',
|
|
349
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
350
|
+
},
|
|
351
|
+
'no-autoplay-audio': {
|
|
352
|
+
check:
|
|
353
|
+
'Open pages that contain media (audio, video, animated content). Does sound start automatically when the page loads? If so, does it play longer than 3 seconds?',
|
|
354
|
+
fix: '(Developer) If auto-play exists and plays longer than 3 seconds, either remove the auto-play or add controls e.g. buttons labelled pause/mute/stop so that users can easily find and activate.',
|
|
355
|
+
review:
|
|
356
|
+
"Reload the page and confirm it is silent by default when it loads. If auto-play audio exists, verify it's only a brief notification (3 seconds or less) or has visible controls.",
|
|
357
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
358
|
+
},
|
|
359
|
+
'color-contrast': {
|
|
360
|
+
check:
|
|
361
|
+
"Scan the page and note specific text that's hard to read: buttons, image captions, footer text, placeholder text in form fields. If you have to focus hard to read it, contrast is likely too low.",
|
|
362
|
+
fix: '(Developer) Adjust text and background colors to meet AA contrast ratio standards. Check using a contrast checking tool.',
|
|
363
|
+
review:
|
|
364
|
+
'Check readability on mobile phones and with dark mode enabled to confirm contrast remains adequate in different viewing conditions.',
|
|
365
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
366
|
+
},
|
|
367
|
+
'color-contrast-enhanced': {
|
|
368
|
+
check:
|
|
369
|
+
'Scan the page and note specific text that could be clearer: buttons, captions, footers, labels. Even if contrast is acceptable for AA, AAA requires even higher contrast for better visibility.',
|
|
370
|
+
fix: '(Developer) Adjust text and background colors to meet AAA contrast ratio standards (higher than AA). Use a contrast checking tool that supports AAA verification.',
|
|
371
|
+
review:
|
|
372
|
+
'Check readability on mobile phones and with dark mode enabled to confirm enhanced contrast is maintained in different viewing conditions.',
|
|
373
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
374
|
+
},
|
|
375
|
+
'frame-focusable-content': {
|
|
376
|
+
check:
|
|
377
|
+
'Use keyboard only (no mouse) to navigate the page. Press Tab to move through interactive elements. When you reach a frame or iframe with interactive content, can you tab into it? Can you interact with content inside it?',
|
|
378
|
+
fix: '(Developer) Ensure frames and iframes with focusable content allow keyboard focus to enter in normal tab order. Do not block keyboard access.',
|
|
379
|
+
review:
|
|
380
|
+
'Test with keyboard: Press Tab to navigate to the frame/iframe and verify you can access interactive content inside. Use keyboard shortcuts specific to the frame content. Shift+Tab back out to confirm keyboard can exit the frame.',
|
|
381
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
382
|
+
},
|
|
383
|
+
'server-side-image-map': {
|
|
384
|
+
check:
|
|
385
|
+
"Open the reported page and locate the image map element. Check if it's a server-side image map (uses server-side processing for clicks).",
|
|
386
|
+
fix: '(Developer) Replace the server-side image map with a client-side image map using HTML <map> and <area> elements, or replace it with standard HTML buttons/links.',
|
|
387
|
+
review:
|
|
388
|
+
'Test with keyboard navigation: Use Tab to navigate and Enter to activate different areas of the map. Confirm all previously clickable areas are now keyboard accessible.',
|
|
389
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
390
|
+
},
|
|
391
|
+
'scrollable-region-focusable': {
|
|
392
|
+
check:
|
|
393
|
+
'Open the reported page and locate the scrollable region. Use keyboard only to try scrolling within this region. Can you reach all interactive elements (buttons, links) inside the scrollable area using Tab?',
|
|
394
|
+
fix: '(Developer) Make interactive elements within the scrollable region focusable and reachable via keyboard with tabindex=0.',
|
|
395
|
+
review:
|
|
396
|
+
'Test with keyboard: Use Tab to reach elements in the scrollable region. Use arrow keys or other keyboard controls to scroll within the region. Confirm all interactive content is accessible.',
|
|
397
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
398
|
+
},
|
|
399
|
+
'oobee-accessible-label': {
|
|
400
|
+
check:
|
|
401
|
+
'Find clickable elements on the page (buttons, links, custom buttons created with code). Check if each has a clear label or text describing its action.',
|
|
402
|
+
fix: '(Developer) Add visible labels or programmatic names that match the action. For elements that should not be keyboard accessible (like decorative interactive elements), use tabindex=-1 to remove them from keyboard navigation.',
|
|
403
|
+
review:
|
|
404
|
+
'Use Tab to navigate to each clickable element and confirm a meaningful name is announced by screen readers.',
|
|
405
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
406
|
+
},
|
|
407
|
+
'meta-refresh': {
|
|
408
|
+
check:
|
|
409
|
+
'Open the page and watch for several minutes: Does the page reload or redirect automatically? If so, how often and without any warning?',
|
|
410
|
+
fix: '(Developer) Remove any timed automatic refresh. If updates are needed, use standard links or buttons that users can click manually.',
|
|
411
|
+
review:
|
|
412
|
+
'Wait on the page again to confirm it does not automatically reload or redirect on its own.',
|
|
413
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
414
|
+
},
|
|
415
|
+
blink: {
|
|
416
|
+
check:
|
|
417
|
+
'Scan the page for any text that blinks, flashes, or moves repeatedly on its own. Look for CSS animations that create blinking effects.',
|
|
418
|
+
fix: '(Developer) Remove any blinking elements or CSS animations that create flashing effects. Replace with static content or use non-animated styling.',
|
|
419
|
+
review: 'Confirm nothing on the page blinks, flashes, or moves continuously on its own.',
|
|
420
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
421
|
+
},
|
|
422
|
+
marquee: {
|
|
423
|
+
check:
|
|
424
|
+
'Scan the page for any text that scrolls, moves horizontally, or animates continuously on its own (e.g., a ticker or scrolling banner).',
|
|
425
|
+
fix: '(Developer) Remove marquee elements and CSS animations that create scrolling text effects. Replace with static content or allow users to control the pace of any necessary animation.',
|
|
426
|
+
review:
|
|
427
|
+
'Confirm nothing scrolls or animates automatically on the page. All content should be readable at a normal pace.',
|
|
428
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
429
|
+
},
|
|
430
|
+
'meta-refresh-no-exceptions': {
|
|
431
|
+
check:
|
|
432
|
+
'Stay on the page for several minutes: Does it reload or redirect automatically without user action? Check if it happens without any user prompts or warnings.',
|
|
433
|
+
fix: '(Developer) Remove meta refresh and any other automatic timed page refresh mechanisms. If users need to access updated content, provide standard links or buttons they can click manually.',
|
|
434
|
+
review:
|
|
435
|
+
'Wait on the page again to confirm it does not automatically refresh or redirect on its own under any circumstances.',
|
|
436
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
437
|
+
},
|
|
438
|
+
bypass: {
|
|
439
|
+
check:
|
|
440
|
+
'Use keyboard navigation (Tab key) on the page: Can you quickly reach the main content without tabbing through all navigation? Is there a main content area marked or a skip link available?',
|
|
441
|
+
fix: '(Developer) Implement a bypass method— mark a main content area with a main landmark, headings so screen readers can navigate to it directly.',
|
|
442
|
+
review:
|
|
443
|
+
'Test keyboard navigation: Use assistive tools (VoiceOver Rotor, Android or NVDA/JAWS shortcuts) to confirm you can reach the main content and sections of the page area quickly without tabbing through repeated navigation blocks.',
|
|
444
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
445
|
+
},
|
|
446
|
+
'document-title': {
|
|
447
|
+
check:
|
|
448
|
+
'Open the page and look at the browser tab: Does the tab title describe the page content? Or does it just say "Untitled" or show the organization name only?',
|
|
449
|
+
fix: '(Developer) Add a short, specific page title that describes the page content. The title should be unique across the site if possible. e.g., "Contact Us"',
|
|
450
|
+
review:
|
|
451
|
+
'Reload the page and confirm the browser tab displays a meaningful title that makes sense for the page.',
|
|
452
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
453
|
+
},
|
|
454
|
+
'link-name': {
|
|
455
|
+
check:
|
|
456
|
+
'Find links on the page (underlined text or styled links). For each link, ask: "Does the link text clearly explain where it goes or what it does?" Look for vague link text like "click here" or "read more".',
|
|
457
|
+
fix: '(Developer) Add descriptive link text that explains the link\'s destination or purpose. e.g., Instead of "click here", use "Learn more about our services".',
|
|
458
|
+
review:
|
|
459
|
+
'Use Tab to navigate through each link and confirm screen readers announce meaningful, descriptive text for each link.',
|
|
460
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
461
|
+
},
|
|
462
|
+
'area-alt': {
|
|
463
|
+
check:
|
|
464
|
+
'Find image maps on the page (images with multiple clickable regions). Use a screen reader to check: Does each clickable area have a text label? Or are regions unlabeled?',
|
|
465
|
+
fix: '(Developer) Add descriptive alt text labels to each clickable area in the image map. e.g., for a map with clickable regions for different cities, each region should be labeled "Click for information about Singapore" or similar. All areas must have labels—no decorative or unlabeled areas.',
|
|
466
|
+
review:
|
|
467
|
+
'Use a screen reader to navigate the image map and confirm each clickable area is announced with its descriptive label.',
|
|
468
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
469
|
+
},
|
|
470
|
+
'identical-links-same-purpose': {
|
|
471
|
+
check:
|
|
472
|
+
'Scan the page for links that use identical text (like multiple "Read more" or "Learn more" links). Note which ones go to different destinations.',
|
|
473
|
+
fix: '(Developer) For each link with identical text going to different pages, add an accessible label (aria-label or title) that specifies the destination. e.g.,: For "Read more" links, add aria-label="Read more about Product A" and aria-label="Read more about Product B".',
|
|
474
|
+
review:
|
|
475
|
+
'Use a screen reader to navigate the page and confirm each identical-text link is announced with its unique accessible label showing the destination or purpose.',
|
|
476
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
477
|
+
},
|
|
478
|
+
'target-size': {
|
|
479
|
+
check:
|
|
480
|
+
'Try to tap buttons and clickable elements on the page, are they hard to tap? Check spacing between adjacent clickable elements.',
|
|
481
|
+
fix: '(Developer) Increase clickable element sizes to at least 24px, or increase the space/padding between adjacent clickable elements. Ensure minimum spacing recommendations are met.',
|
|
482
|
+
review:
|
|
483
|
+
'Test again with touch or by simulating small target areas: Confirm buttons and clickable elements are now easy to tap accurately without accidentally clicking nearby elements.',
|
|
484
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
485
|
+
},
|
|
486
|
+
'html-has-lang': {
|
|
487
|
+
check: 'Identify what language the page is written in (e.g., English).',
|
|
488
|
+
fix: '(Developer) Set the language attribute on the page and on any frames/iframes. Use the correct language code (e.g., lang="en" for English).',
|
|
489
|
+
review:
|
|
490
|
+
'Open the page and a localized version if available. Confirm the language attribute is set correctly on each.',
|
|
491
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
492
|
+
},
|
|
493
|
+
'html-lang-valid': {
|
|
494
|
+
check:
|
|
495
|
+
'Check the page\'s language declaration. Is it using a valid ISO language code (like "en")? Or is it using something invalid or unclear?',
|
|
496
|
+
fix: '(Developer) Fix the language code on the page to use a valid ISO code. e.g., "en" (English), "en-US" (US English)',
|
|
497
|
+
review:
|
|
498
|
+
'Verify the corrected language code is saved. Open the page and confirm screen readers and translation tools now recognize the language correctly.',
|
|
499
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
500
|
+
},
|
|
501
|
+
'html-xml-lang-mismatch': {
|
|
502
|
+
check:
|
|
503
|
+
'Check if the page or any elements use different lang attributes. If so, verify they use the same language code.',
|
|
504
|
+
fix: '(Developer) Ensure different lang attributes match on the same elements. Set both to the same valid language code. e.g.,: Set both to lang="en" and xml:lang="en".',
|
|
505
|
+
review:
|
|
506
|
+
'Verify the matching language declarations are saved. Open the page and test that screen readers recognize the language correctly.',
|
|
507
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
508
|
+
},
|
|
509
|
+
'valid-lang': {
|
|
510
|
+
check:
|
|
511
|
+
"Identify any content on the page that uses different languages than the page's main language. Check if those elements have language attributes.",
|
|
512
|
+
fix: '(Developer) Add valid language codes to elements in different languages. Use valid ISO codes e.g., "es" for Spanish sections. <p lang="es">Este es un párrafo en español</p>.',
|
|
513
|
+
review:
|
|
514
|
+
'Test with a screen reader: Navigate to content in different languages and confirm the screen reader switches to correct pronunciation for each language.',
|
|
515
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
516
|
+
},
|
|
517
|
+
'oobee-grading-text-contents': {
|
|
518
|
+
check:
|
|
519
|
+
'Identify the pages with the most complex or dense text content. Highlight sentences that are very long or use jargon/technical terms unfamiliar to general audiences.',
|
|
520
|
+
fix: 'Rewrite complex sections using shorter sentences, common words, and one idea per sentence. Define any necessary technical terms. Remove or simplify jargon.',
|
|
521
|
+
review:
|
|
522
|
+
'Ask a colleague unfamiliar with the topic to read the revised content and explain it back in their own words. If they struggle to understand, simplify further.',
|
|
523
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
524
|
+
},
|
|
525
|
+
'form-field-multiple-labels': {
|
|
526
|
+
check:
|
|
527
|
+
'Find form fields on the page that display more than one label or title. Check if there are multiple label elements pointing to the same field.',
|
|
528
|
+
fix: '(Developer) Keep only one main label per field. Move extra text (hints, error messages) to separate help or error areas instead of making them labels.',
|
|
529
|
+
review:
|
|
530
|
+
'Use a screen reader to tab through form fields and confirm each field announces only one clear label. Click the label and verify it correctly focuses the associated field.',
|
|
531
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
532
|
+
},
|
|
533
|
+
'aria-allowed-attr': {
|
|
534
|
+
check:
|
|
535
|
+
'Find the elements identified in the report on the page. Check what ARIA attributes are applied to them.',
|
|
536
|
+
fix: "(Developer) Remove invalid ARIA attributes from elements that don't support them (this will revert the element to its normal implicit behavior), or move the ARIA attributes to the correct element type that supports them.",
|
|
537
|
+
review:
|
|
538
|
+
'Use a screen reader to navigate to those elements and confirm they now announce correctly with normal name and type.',
|
|
539
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
540
|
+
},
|
|
541
|
+
'aria-braille-equivalent': {
|
|
542
|
+
check:
|
|
543
|
+
'Find controls or elements that have braille-specific abbreviated labels or descriptions (labels written specifically for braille displays).',
|
|
544
|
+
fix: '(Developer) Add a full, non-abbreviated equivalent label. For example, if aria-braillelabel="vol", also provide aria-label="volume" or a full text label that braille and non-braille users both see.',
|
|
545
|
+
review:
|
|
546
|
+
'Test with both braille and non-braille screen readers to confirm the control is announced clearly with the full equivalent. Both methods should provide the same information.',
|
|
547
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
548
|
+
},
|
|
549
|
+
'aria-command-name': {
|
|
550
|
+
check:
|
|
551
|
+
'Find elements like role="button" that don\'t have visible text or labels. Check: Does each have text inside it, an aria-label, or a title attribute describing what it does?',
|
|
552
|
+
fix: '(Developer) Add accessible labels using one of these methods: (1) Visible text inside the element, (2) aria-label attribute, (3) aria-labelledby pointing to another element with text, or (4) title attribute. e.g.,: role="button" aria-label="Save document" or title="Delete item".',
|
|
553
|
+
review:
|
|
554
|
+
'Use a screen reader to Tab through command elements and confirm each announces what it does (e.g., "Save document button").',
|
|
555
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
556
|
+
},
|
|
557
|
+
'aria-conditional-attr': {
|
|
558
|
+
check:
|
|
559
|
+
'Find elements identified in the issue. Check: Do the accessibility attributes on this element match the actual state of the element? Or do they contradict each other? Look for elements where the type and behavior seem confused.',
|
|
560
|
+
fix: '(Developer) Remove or replace conflicting ARIA attributes. Prefer native HTML elements and implicit attributes: Use <button> instead of <div role="button">. Use <a> for links instead of <div role="link">. Remove ARIA attributes that create conflicts or unclear states.',
|
|
561
|
+
review:
|
|
562
|
+
'Use a screen reader to navigate the element and confirm it now announces clearly without conflicting information. The element should sound like one clear type (button, link, etc.), not confused or contradictory.',
|
|
563
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
564
|
+
},
|
|
565
|
+
'aria-deprecated-role': {
|
|
566
|
+
check:
|
|
567
|
+
'Find elements listed in the issue that use outdated roles. Note the role names. Ask: Are these controlling buttons, tabs, menus, or other interactive elements?',
|
|
568
|
+
fix: '(Developer) Replace each outdated role with a current supported role, or replace with a native HTML element (like real <button> or <a> instead of custom code).',
|
|
569
|
+
review:
|
|
570
|
+
"Use a screen reader to test: Navigate to each updated element and confirm it's announced correctly (as a button, tab, menu, etc.).",
|
|
571
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
572
|
+
},
|
|
573
|
+
'aria-hidden-body': {
|
|
574
|
+
check:
|
|
575
|
+
'Check if the page body has aria-hidden="true" applied to it. This would hide all content from screen readers.',
|
|
576
|
+
fix: '(Developer) Remove aria-hidden="true" from the body element or any wrapper containing the main page content.',
|
|
577
|
+
review:
|
|
578
|
+
'Use a screen reader to confirm the page content is now readable and all text and interactive elements are announced.',
|
|
579
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
580
|
+
},
|
|
581
|
+
'aria-hidden-focus': {
|
|
582
|
+
check:
|
|
583
|
+
'Locate the elements identified in the issue that are marked as hidden. Check: Do they contain buttons, links, form fields, or other interactive elements that can be focused via keyboard?',
|
|
584
|
+
fix: '(Developer) Either remove aria-hidden="true" from the container, or remove keyboard focus from the interactive elements inside it using tabindex="-1".',
|
|
585
|
+
review:
|
|
586
|
+
'Test with keyboard: Use Tab to navigate through the page. Confirm you cannot tab into content that is hidden from screen readers. If you can tab to it, you can hear it announced.',
|
|
587
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
588
|
+
},
|
|
589
|
+
'aria-input-field-name': {
|
|
590
|
+
check:
|
|
591
|
+
'Find custom input fields on the page. Check each one: Does it have a visible label or associated text describing what to enter?',
|
|
592
|
+
fix: '(Developer) Add an accessible label to each input using aria-label or by associating a visible label element. e.g., aria-label="Email address".',
|
|
593
|
+
review:
|
|
594
|
+
'Use a screen reader to Tab through input fields and confirm each announces its label/purpose clearly.',
|
|
595
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
596
|
+
},
|
|
597
|
+
'aria-prohibited-attr': {
|
|
598
|
+
check:
|
|
599
|
+
'Find the elements identified in the issue. Check: What ARIA attributes do they have applied? Are those attributes appropriate for this element type?',
|
|
600
|
+
fix: '(Developer) Remove ARIA attributes that are not permitted on these elements according to the accessibility specification.',
|
|
601
|
+
review:
|
|
602
|
+
'Test with a screen reader: Navigate to the element and confirm it now announces correctly without conflicting or confusing information.',
|
|
603
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
604
|
+
},
|
|
605
|
+
'aria-required-attr': {
|
|
606
|
+
check:
|
|
607
|
+
'Identify each interactive element mentioned in the issue (tabs, sliders, etc.). Check: Does it have all the required ARIA attributes for its role?',
|
|
608
|
+
fix: "(Developer) Add the missing required ARIA attributes for each element's role. e.g., For tabs, add aria-selected.",
|
|
609
|
+
review:
|
|
610
|
+
'Use a screen reader to interact with the element and confirm it announces the name, state, and current value correctly.',
|
|
611
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
612
|
+
},
|
|
613
|
+
'aria-roles': {
|
|
614
|
+
check:
|
|
615
|
+
'Find elements identified in the issue. Check: Do they have ARIA role attributes? Are those role names valid and supported (like "button", "link")? Or are they misspelled or unsupported?',
|
|
616
|
+
fix: '(Developer) Replace invalid role names with valid, supported ones. If no valid role exists for the element, replace with a native HTML element (real <button>, <a>, <input>) instead.',
|
|
617
|
+
review:
|
|
618
|
+
"Use a screen reader and keyboard to test: Tab to the element and confirm it's announced correctly (as a button, link, or other expected type). Confirm keyboard activation works as expected.",
|
|
619
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
620
|
+
},
|
|
621
|
+
'aria-toggle-field-name': {
|
|
622
|
+
check:
|
|
623
|
+
'Find toggle switches or checkbox-style controls on the page. Check: Does each have a visible label or descriptive text? Or is it labeled vaguely like "On/Off" without context?',
|
|
624
|
+
fix: '(Developer) Add descriptive labels or aria-labels to each toggle. e.g., aria-label="Dark mode toggle", or visible text saying "Dark mode".',
|
|
625
|
+
review:
|
|
626
|
+
'Use a screen reader to Tab through toggles and confirm each announces what will be toggled.',
|
|
627
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
628
|
+
},
|
|
629
|
+
'aria-tooltip-name': {
|
|
630
|
+
check:
|
|
631
|
+
'Find tooltips on the page. Check: Does each have a visible label or aria-label describing what it does?',
|
|
632
|
+
fix: '(Developer) Add labels using visible text, title attribute, or aria-label. e.g., aria-label="Save document", title="Print page"',
|
|
633
|
+
review:
|
|
634
|
+
'Use a screen reader to Tab to buttons and confirm each announces what it does (e.g., "Save document button" not just "button").',
|
|
635
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
636
|
+
},
|
|
637
|
+
'aria-valid-attr': {
|
|
638
|
+
check:
|
|
639
|
+
'Find elements identified in the issue. Check their ARIA attributes: Are they spelled correctly? Are they documented, supported attribute names? Look for common typos.',
|
|
640
|
+
fix: '(Developer) Correct any misspelled or unsupported ARIA attribute names to valid, documented ones. Use official ARIA attribute reference to verify correct spelling.',
|
|
641
|
+
review:
|
|
642
|
+
'Test with a screen reader and confirm elements now announce correctly with the corrected attributes. No missing or odd announcements.',
|
|
643
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
644
|
+
},
|
|
645
|
+
'aria-valid-attr-value': {
|
|
646
|
+
check:
|
|
647
|
+
'Find elements identified in the issue. Check: What values are assigned to their ARIA attributes? Are they valid according to the ARIA specification? Or are they using invalid/unsupported values?',
|
|
648
|
+
fix: '(Developer) Change each ARIA attribute value to a valid, supported value. e.g., Change aria-pressed="yes" to aria-pressed="true"',
|
|
649
|
+
review:
|
|
650
|
+
'Use a screen reader to test elements and confirm they now announce the correct state or value.',
|
|
651
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
652
|
+
},
|
|
653
|
+
'button-name': {
|
|
654
|
+
check:
|
|
655
|
+
"Find buttons on the page that don't have text inside them or visible labels. e.g., icon-only buttons",
|
|
656
|
+
fix: '(Developer) Add descriptive text. This can be: (1) Text inside the button ("Save", "Submit"), (2) aria-label attribute ("Save document", "Submit form"), or (3) title attribute with the action.',
|
|
657
|
+
review:
|
|
658
|
+
'Use a screen reader to Tab through buttons and confirm each announces what it does (e.g., "Save button", "Delete item button").',
|
|
659
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
660
|
+
},
|
|
661
|
+
'duplicate-id-aria': {
|
|
662
|
+
check:
|
|
663
|
+
'Find elements that use duplicate IDs—especially form fields and elements referenced by labels or ARIA attributes. Check the page source or use developer tools to identify duplicates.',
|
|
664
|
+
fix: '(Developer) Give each element a unique ID. Update any labels or ARIA references (like aria-labelledby) to point to the correct unique ID. e.g., Change duplicate id="email" to id="email-address" and id="email-subscribe".',
|
|
665
|
+
review:
|
|
666
|
+
'Test form fields and labels: Click each label and verify it focuses only its intended field. Use Tab to navigate and confirm focus works correctly.',
|
|
667
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
668
|
+
},
|
|
669
|
+
'frame-title': {
|
|
670
|
+
check:
|
|
671
|
+
'Find all frames and iframes on the page—maps, videos, widgets, etc. Check if each has a title attribute. If not, note what it contains.',
|
|
672
|
+
fix: '(Developer) Add a descriptive title attribute to each frame. e.g., title="Location map showing branch offices"',
|
|
673
|
+
review:
|
|
674
|
+
'Use a screen reader and Tab through the page. When you reach each frame/iframe, confirm its title is announced.',
|
|
675
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
676
|
+
},
|
|
677
|
+
'frame-title-unique': {
|
|
678
|
+
check:
|
|
679
|
+
'Identify pages with multiple frames or iframes of the same type (like multiple videos, etc.). Check: Do they all have the same title? Or unique titles?',
|
|
680
|
+
fix: '(Developer) Give each frame a unique, descriptive title that distinguishes it. e.g., "Product demo video" vs. "Customer testimonial video".',
|
|
681
|
+
review:
|
|
682
|
+
'Use a screen reader and Tab to each frame. Confirm each frame announces a unique title that helps distinguish it from other frames.',
|
|
683
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
684
|
+
},
|
|
685
|
+
'input-button-name': {
|
|
686
|
+
check:
|
|
687
|
+
"Find input-based buttons on the page that don't have visible text or labels. e.g., submit buttons with no text, image buttons without alt text.",
|
|
688
|
+
fix: '(Developer) Add descriptive text: (1) For <input type="submit">, add a value attribute like value="Submit Form". (2) For <input type="image">, add alt text like alt="Search button".',
|
|
689
|
+
review:
|
|
690
|
+
'Use a screen reader to Tab through buttons and confirm each announces its purpose (e.g., "Submit form button").',
|
|
691
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
692
|
+
},
|
|
693
|
+
label: {
|
|
694
|
+
check:
|
|
695
|
+
'Find form fields on the page without visible labels or programmatic labels. Check: Does each field have text near it explaining what to enter? Or can you see what the field is for?',
|
|
696
|
+
fix: '(Developer) Associate labels with fields: (1) Use <label> elements with for attribute pointing to the field\'s ID, (2) Or use aria-label/aria-labelledby on the field. e.g., <label for="email">Email address:</label> <input id="email">.',
|
|
697
|
+
review:
|
|
698
|
+
'Use a screen reader to Tab through form fields and confirm each announces its label. Click visible labels and verify they focus the corresponding field.',
|
|
699
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
700
|
+
},
|
|
701
|
+
'nested-interactive': {
|
|
702
|
+
check:
|
|
703
|
+
'Find nested interactive elements on the page. Use Tab or inspect the HTML: Are buttons inside links, links inside buttons, or multiple interactive elements nested together?',
|
|
704
|
+
fix: '(Developer) Restructure the HTML to remove nesting. Make interactive elements siblings instead of nested. If you need multiple actions, use separate buttons/links at the same level.',
|
|
705
|
+
review:
|
|
706
|
+
"Use Tab and click: Confirm you can click and interact with each interactive element separately. Use a screen reader to verify no confusion about what's clickable.",
|
|
707
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
708
|
+
},
|
|
709
|
+
'select-name': {
|
|
710
|
+
check:
|
|
711
|
+
"Find select dropdowns on the page. Check each one: Does it have a visible label explaining what the dropdown controls? Or can you tell what it's for without reading surrounding text?",
|
|
712
|
+
fix: '(Developer) Associate labels with select elements: (1) Use <label> elements with for attribute pointing to the select\'s ID, (2) Or use aria-label/aria-labelledby. e.g., <label for="country">Choose your country:</label> <select id="country">.',
|
|
713
|
+
review:
|
|
714
|
+
'Use a screen reader to Tab to each dropdown and confirm it announces the label. Open the dropdown and confirm options are readable.',
|
|
715
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
716
|
+
},
|
|
717
|
+
accesskeys: {
|
|
718
|
+
check:
|
|
719
|
+
'Find elements with accesskey attributes on the page. List which keys are used. Are any duplicates? Do any conflict with common browser/system shortcuts (Ctrl+S, Ctrl+P, etc.)?',
|
|
720
|
+
fix: '(Developer) Remove duplicate access keys. Rename conflicting keys to avoid browser/system conflicts. Document all access keys on a help page so users know they exist. e.g., "Press Alt+S to search".',
|
|
721
|
+
review:
|
|
722
|
+
"Test: Press each documented access key and confirm only one action fires. Verify access keys don't conflict with browser functions (like opening the File menu).",
|
|
723
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
724
|
+
},
|
|
725
|
+
'aria-dialog-name': {
|
|
726
|
+
check:
|
|
727
|
+
'Open popup or modal dialogs on the page. Check each one: Does it have a visible title at the top explaining its purpose? Or any accessible label? e.g., "Confirm delete", "Sign in".',
|
|
728
|
+
fix: '(Developer) Add a clear, descriptive title/label to each dialog: (1) Visible text at the top of the dialog, (2) aria-label or title attribute on the dialog container, or (3) aria-labelledby pointing to the title element.',
|
|
729
|
+
review:
|
|
730
|
+
'Use a screen reader to open each dialog and confirm it announces the dialog type and reads the title/purpose clearly.',
|
|
731
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
732
|
+
},
|
|
733
|
+
'aria-text': {
|
|
734
|
+
check:
|
|
735
|
+
'Navigate through the page text with a screen reader. Identify if any interactive elements inside text-only role that are not correctly focussed or announced by screen reader.',
|
|
736
|
+
fix: '(Developer) Remove interactive elements from text elements. If interactive content must be inside, remove the text role or make the interactive element focusable at a higher level.',
|
|
737
|
+
review:
|
|
738
|
+
'Use a screen reader and navigate through the page and confirm interactive elements (buttons, links, form fields) receive focus.',
|
|
739
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
740
|
+
},
|
|
741
|
+
'aria-treeitem-name': {
|
|
742
|
+
check:
|
|
743
|
+
'Find tree or expandable list items on the page (like file explorers or navigation trees). Check each item: Does it have visible text describing what it is? Can you tell items apart?',
|
|
744
|
+
fix: '(Developer) Add accessible labels to each tree item: (1) Visible text inside the item, (2) title, (3) aria-label attribute, or (4) aria-labelledby pointing to text elsewhere. e.g., "Folder: Documents", "File: Report.pdf".',
|
|
745
|
+
review:
|
|
746
|
+
'Use a screen reader to navigate through tree items and confirm each announces its name. Use arrow keys to expand/collapse and verify screen reader announces state changes.',
|
|
747
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
748
|
+
},
|
|
749
|
+
'empty-heading': {
|
|
750
|
+
check:
|
|
751
|
+
'Skim the page and look for empty heading elements (h1, h2, h3, etc.) that have no text content or only contain images/icons without text.',
|
|
752
|
+
fix: '(Developer) Remove empty headings entirely, remove aria-hidden="true", or add meaningful text that describes the section. e.g.,: "Features", "Contact information".',
|
|
753
|
+
review:
|
|
754
|
+
"Use a screen reader to review the page's heading structure and confirm no headings are empty. Use a heading navigation list to verify all headings have descriptive text.",
|
|
755
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
756
|
+
},
|
|
757
|
+
'empty-table-header': {
|
|
758
|
+
check:
|
|
759
|
+
'Inspect data tables on the page for empty header cells (column or row headers with no text content). Check: Do all headers have labels? Or are some blank?',
|
|
760
|
+
fix: '(Developer) Add descriptive text to each header cell. e.g., Column headers might be "Name". Row headers might be "Q1 Sales". Remove aria-label/aria-labelledby attribute to each header cell.',
|
|
761
|
+
review:
|
|
762
|
+
"Use a screen reader to move cell-by-cell through the table and confirm each data cell's header is announced. The announcement should make clear what data is in each cell.",
|
|
763
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
764
|
+
},
|
|
765
|
+
'frame-tested': {
|
|
766
|
+
check:
|
|
767
|
+
'Open a page containing embedded frames or iframes (videos, widgets etc). Run a scan and check: Does it report issues in the frames? Or is frame content being skipped?',
|
|
768
|
+
fix: '(Developer) Test frames with Oobee to surface any issues inside them. Configure tools to scan frames when possible. Fix accessibility issues found within frames. Ensure third-party content meets accessibility standards.',
|
|
769
|
+
review:
|
|
770
|
+
'Test keyboard navigation across the page: Tab into and out of frames. Confirm all interactive content in frames is keyboard accessible. Retest with Oobee to confirm frame content is now properly analyzed and accessible.',
|
|
771
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
772
|
+
},
|
|
773
|
+
'heading-order': {
|
|
774
|
+
check:
|
|
775
|
+
"Use the browser's headings outline or a screen reader to view the heading structure. Check: Does the page have one H1 at the top? Do headings increase logically (H1 → H2)? Or are levels skipped or out of order?",
|
|
776
|
+
fix: "(Developer) Restructure headings to follow proper order: Set one H1 for the main page title. Use H2 for primary sections. Use H3 for subsections within H2. Don't skip levels. Use CSS styles to modify the size of text.",
|
|
777
|
+
review:
|
|
778
|
+
'Review the heading outline/list with a screen reader to confirm all headings are in logical, hierarchical order with no gaps or backwards jumps.',
|
|
779
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
780
|
+
},
|
|
781
|
+
'image-redundant-alt': {
|
|
782
|
+
check:
|
|
783
|
+
'Find images with alt text on the page. For each image, check: Is there text near the image saying the same thing? Would a screen reader user hear the information twice?',
|
|
784
|
+
fix: '(Developer) For images that are decorative or just illustrate existing text, use empty alt: alt="". For informative images, write alt text that adds new information or context not already in nearby text.',
|
|
785
|
+
review:
|
|
786
|
+
'Use a screen reader to read through the page and confirm no information is announced twice. Images should either add new information or have empty alt if decorative.',
|
|
787
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
788
|
+
},
|
|
789
|
+
'label-title-only': {
|
|
790
|
+
check:
|
|
791
|
+
'Find form fields on the page. Check each one: Is there visible text labeling the field? Or is the label hidden, only appearing as a tooltip on hover, or in placeholder text only?',
|
|
792
|
+
fix: "(Developer) Add visible text labels next to or above each form field. Use <label> elements properly associated with fields. Place labels where they're always visible—not in tooltips or placeholders.",
|
|
793
|
+
review:
|
|
794
|
+
'Visually scan the page and verify every form field has a visible label. Tab through with a screen reader and confirm the label is announced.',
|
|
795
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
796
|
+
},
|
|
797
|
+
'landmark-banner-is-top-level': {
|
|
798
|
+
check:
|
|
799
|
+
'Check the page structure: Is the header (banner landmark) at the very top level? Or is it nested inside the main content area or another landmark? Use a landmark navigator or browser inspector to verify.',
|
|
800
|
+
fix: '(Developer) Move the header/banner landmark to the top level of the page, outside the main content and other landmarks. Structure should be: header, then main content, then sidebar, then footer.',
|
|
801
|
+
review:
|
|
802
|
+
'Use a landmark navigator (or screen reader landmark commands) to jump between page regions. Confirm you can reach the header directly without being trapped inside other content areas.',
|
|
803
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
804
|
+
},
|
|
805
|
+
'landmark-complementary-is-top-level': {
|
|
806
|
+
check:
|
|
807
|
+
'Check the page structure: Is the sidebar (complementary landmark) at the top level? Or nested inside the main content or another landmark? Use a landmark navigator to verify.',
|
|
808
|
+
fix: '(Developer) Move the sidebar/complementary landmark to the top level, outside the main content. Structure should be: header, main content, sidebar, footer.',
|
|
809
|
+
review:
|
|
810
|
+
'Use a landmark navigator to jump to the sidebar region. Confirm you can reach it directly at the top level without being trapped inside other areas.',
|
|
811
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
812
|
+
},
|
|
813
|
+
'landmark-contentinfo-is-top-level': {
|
|
814
|
+
check:
|
|
815
|
+
'Check the page structure: Is the footer (contentinfo landmark) at the top level? Or nested inside the main content or another landmark? Use a landmark navigator to verify.',
|
|
816
|
+
fix: '(Developer) Move the footer/contentinfo landmark to the top level of the page, outside all other content areas. Proper structure: header, main, sidebar, then footer.',
|
|
817
|
+
review:
|
|
818
|
+
'Use a landmark navigator to jump to the footer. Confirm you can reach it at the top level. Use a screen reader skip link or landmark navigation to verify you can access footer content without scrolling through all main content.',
|
|
819
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
820
|
+
},
|
|
821
|
+
'landmark-main-is-top-level': {
|
|
822
|
+
check:
|
|
823
|
+
'Check the page structure: Is the main content landmark at the top level? Or nested inside other landmarks or containers? Use a landmark navigator or page outline to verify.',
|
|
824
|
+
fix: '(Developer) Restructure the page so the main content region is at the top level, alongside but separate from header, sidebar, and footer regions.',
|
|
825
|
+
review:
|
|
826
|
+
'Use keyboard shortcuts or landmark navigation to jump directly to the main content. Confirm you can reach it quickly from any page location without navigating through other regions first.',
|
|
827
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
828
|
+
},
|
|
829
|
+
'landmark-no-duplicate-banner': {
|
|
830
|
+
check:
|
|
831
|
+
'Use a landmark navigator or screen reader to scan the page. Count how many header/banner landmarks exist. Are there multiple headers? Or just one at the top?',
|
|
832
|
+
fix: '(Developer) Combine multiple headers into one. Remove duplicate headers. Keep only one main header/banner landmark at the top of the page.',
|
|
833
|
+
review:
|
|
834
|
+
'Verify with a landmark navigator that the page now has exactly one header/banner region. Use screen reader landmark commands to confirm only one header is announced.',
|
|
835
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
836
|
+
},
|
|
837
|
+
'landmark-no-duplicate-contentinfo': {
|
|
838
|
+
check:
|
|
839
|
+
'Use a landmark navigator or screen reader to scan the page. Count how many footer/contentinfo landmarks exist. Are there multiple footers? Or just one at the bottom?',
|
|
840
|
+
fix: '(Developer) Combine multiple footers into one. Remove duplicate footers. Keep only one main footer/contentinfo landmark at the bottom of the page.',
|
|
841
|
+
review:
|
|
842
|
+
'Verify with a landmark navigator that the page now has exactly one footer/contentinfo region. Use screen reader landmark commands to confirm only one footer is announced.',
|
|
843
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
844
|
+
},
|
|
845
|
+
'landmark-no-duplicate-main': {
|
|
846
|
+
check:
|
|
847
|
+
'Use a landmark navigator or screen reader to scan the page. Count how many main content landmarks exist. Is there more than one? Or just one?',
|
|
848
|
+
fix: "(Developer) Consolidate into one main region. Remove or reclassify any duplicate main landmarks. Keep only one main landmark containing the page's primary content. Secondary content should use other landmarks (complementary, regions, etc.).",
|
|
849
|
+
review:
|
|
850
|
+
'Verify with a landmark navigator that the page now has exactly one main region. Use screen reader landmark navigation to confirm only one main content area is announced.',
|
|
851
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
852
|
+
},
|
|
853
|
+
'landmark-one-main': {
|
|
854
|
+
check:
|
|
855
|
+
'Check if the page has a marked main content region. Is there a <main> element or an element with role="main"? Or does the page lack a clear main content area?',
|
|
856
|
+
fix: '(Developer) Add a main landmark that wraps the primary page content. Use the semantic <main> element, or use role="main" on a <div>. All important page content should be inside this region.',
|
|
857
|
+
review:
|
|
858
|
+
'Use a landmark navigator or screen reader to jump to the main region. Confirm you can reach the primary content directly without navigating through other page areas first.',
|
|
859
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
860
|
+
},
|
|
861
|
+
'landmark-unique': {
|
|
862
|
+
check:
|
|
863
|
+
'Use a landmark navigator to scan the page. Are there multiple regions with the same type? Do they have different labels, or are they identical and indistinguishable?',
|
|
864
|
+
fix: '(Developer) If there are multiple landmarks of the same type, add unique labels using aria-label or aria-labelledby. e.g., role="complementary" aria-label="Featured products sidebar".',
|
|
865
|
+
review:
|
|
866
|
+
'Use a landmark navigator and verify each region is announced with its unique label. Confirm you can distinguish one from another.',
|
|
867
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
868
|
+
},
|
|
869
|
+
'meta-viewport-large': {
|
|
870
|
+
check:
|
|
871
|
+
'On a mobile device or mobile browser view, try to pinch-zoom (pinch your fingers apart) to enlarge the page. Does it zoom in? Or is zoom blocked and the page stays the same size?',
|
|
872
|
+
fix: '(Developer) Check the viewport meta tag. It should NOT have user-scalable="no" or maximum-scale="1". Allow zooming by either removing these restrictions or setting maximum-scale to 2 or higher.',
|
|
873
|
+
review:
|
|
874
|
+
'Test on mobile: Pinch-zoom to enlarge content to 200%. Confirm text is readable and buttons/controls are still usable and clickable at larger zoom levels.',
|
|
875
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
876
|
+
},
|
|
877
|
+
'page-has-heading-one': {
|
|
878
|
+
check:
|
|
879
|
+
'Look at the page and check: Is there a main page title or headline at the top? Is it marked as an H1 heading? Or is there no H1, or multiple H1s?',
|
|
880
|
+
fix: "(Developer) Add one H1 heading at the top of the page content that describes the page's main topic. Use <h1> tags. This should be the page title or main section. After H1, use H2 for main sections, H3 for subsections, etc.",
|
|
881
|
+
review:
|
|
882
|
+
"Use a screen reader or headings list to verify the page has one or more H1 and it's the first heading on the page.",
|
|
883
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
884
|
+
},
|
|
885
|
+
'presentation-role-conflict': {
|
|
886
|
+
check:
|
|
887
|
+
'Tab through the page looking for odd focus behavior. Do you get stuck on decorative elements? Do some elements receive focus but seem to have no purpose?',
|
|
888
|
+
fix: '(Developer) Remove role="presentation" or role="none" from interactive elements, OR remove interactive behavior and focus from purely decorative elements. Don\'t mark the element as aria-hidden="true" if role="role="presentation" or role="none" is used as this changes the semantic meaning of the element for screen reader users.',
|
|
889
|
+
review:
|
|
890
|
+
'Test with Tab: Navigate through the page in order from top to bottom. Confirm only meaningful interactive elements (buttons, links, form fields) receive focus. Decorative elements should be skipped.',
|
|
891
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
892
|
+
},
|
|
893
|
+
region: {
|
|
894
|
+
check:
|
|
895
|
+
'Check the page structure: Is all meaningful content inside marked regions or landmarks? Or is there orphaned content outside any landmark? Look for text, buttons, or links that float outside structural areas.',
|
|
896
|
+
fix: '(Developer) Wrap all page content in appropriate landmarks: <header>, <main>, <footer>, <nav>, <aside>, or <section role="region">. Every piece of content should belong to one of these sections.',
|
|
897
|
+
review:
|
|
898
|
+
'Use a landmark navigator to verify all page content is inside landmarks. Keyboard navigation should move smoothly between regions with no orphaned content.',
|
|
899
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
900
|
+
},
|
|
901
|
+
'scope-attr-valid': {
|
|
902
|
+
check:
|
|
903
|
+
'Pick a table with headers. Check the headers: Do they use scope="col" for column headers? Do they use scope="row" for row headers? Or are scope values missing or incorrect?',
|
|
904
|
+
fix: '(Developer) Add correct scope attributes to all table headers. Use scope="col" for headers that label columns. Use scope="row" for headers that label rows.',
|
|
905
|
+
review:
|
|
906
|
+
'Use a screen reader to navigate the table cell-by-cell. Confirm that as you move through cells, the correct header (column or row) is announced.',
|
|
907
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
908
|
+
},
|
|
909
|
+
'skip-link': {
|
|
910
|
+
check:
|
|
911
|
+
'Open the page and press Tab immediately. Does a "Skip to content" or similar link appear? If yes, click it or press Enter. Does it jump to the main content? Or does it fail?',
|
|
912
|
+
fix: '(Developer) Ensure the skip link exists as the first focusable element. Make sure the hyperlink points to a valid target of the same page (e.g. href="#maincontent"). Test that clicking the link actually moves focus to that target.',
|
|
913
|
+
review:
|
|
914
|
+
'Test with keyboard: Press Tab to reveal the skip link. Press Enter to activate it. Confirm your focus moves to the main content area and you can continue from there.',
|
|
915
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
916
|
+
},
|
|
917
|
+
tabindex: {
|
|
918
|
+
check:
|
|
919
|
+
'Use Tab to navigate through the page from top to bottom. Does focus move in a logical, left-to-right, top-to-bottom order? Or does it jump around randomly?',
|
|
920
|
+
fix: '(Developer) Search the HTML for any tabindex attributes with positive numbers (1, 2, 3, etc.) and remove them. Use tabindex="0" to include elements in normal tab order, or tabindex="-1" to exclude them. Finally check that HTML elements are ordered semantically in a logical way from top to bottom, and re-order them where necessary.',
|
|
921
|
+
review:
|
|
922
|
+
'Test keyboard navigation again: Tab from the top of the page down. Focus should move in a logical, predictable order. No random jumps or skips.',
|
|
923
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
924
|
+
},
|
|
925
|
+
'table-duplicate-name': {
|
|
926
|
+
check:
|
|
927
|
+
'Find tables with both a <caption> element and a summary attribute (or aria-label). Check: Do they say the same thing? Or does each add different information?',
|
|
928
|
+
fix: '(Developer) If caption and summary are identical, remove one. Keep the caption. Or revise the summary to add context or explanation not already in the caption.',
|
|
929
|
+
review:
|
|
930
|
+
'Use a screen reader to navigate the table and confirm the caption/summary is announced once with clear information. No duplicate announcements.',
|
|
931
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
932
|
+
},
|
|
933
|
+
'meta-viewport': {
|
|
934
|
+
check:
|
|
935
|
+
'Test zooming: On desktop, use browser zoom (Ctrl and +, or Cmd and +). On laptop or mobile, pinch your fingers apart to zoom. Can you enlarge the page content? Or is zoom blocked and nothing happens?',
|
|
936
|
+
fix: '(Developer) Check the <meta name="viewport"> tag in the page\'s HTML. Remove or change: user-scalable="no" (change to user-scalable="yes"), and maximum-scale="1" (increase to at least 2). e.g., <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2, user-scalable=yes">.',
|
|
937
|
+
review:
|
|
938
|
+
'Test zoom on both desktop and mobile: Zoom to 200% (double size). Confirm text is readable, buttons are clickable, and page functionality works normally at larger zoom levels.',
|
|
939
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
940
|
+
},
|
|
941
|
+
'aria-allowed-role': {
|
|
942
|
+
check:
|
|
943
|
+
'Find elements that look clickable on the page. Ask: Does this do something (like submit a form or open a menu)? Or does it go somewhere else (navigate to a new page)? Check if the label matches what it actually does.',
|
|
944
|
+
fix: '(Developer) Use real <button> for actions, real <a> for navigation links. If you must use code to create buttons or links, make sure they actually behave like real ones—buttons activate with Space/Enter, links activate with Enter and navigate away.',
|
|
945
|
+
review: `Test with keyboard: Try clicking buttons (Space or Enter), try clicking links (Enter). Use a screen reader to hear if it's announced as a button or link. Confirm what it announces matches what it actually does.`,
|
|
946
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
947
|
+
},
|
|
948
|
+
'summary-name': {
|
|
949
|
+
check:
|
|
950
|
+
'Find summary elements with and check if text is inside, or has a label (aria-label or title). Check: Do they convey meaningful information about the details?',
|
|
951
|
+
fix: '(Developer) If summary are missing text or labels, add one to provide context or explanation to the details.',
|
|
952
|
+
review:
|
|
953
|
+
'Use a screen reader to navigate to the summary and ensure it is announced with clear information.',
|
|
954
|
+
learn: 'Review and learn more about this issue on A11y Playground',
|
|
955
|
+
},
|
|
956
|
+
};
|
|
957
|
+
</script>
|