---
title: "ACT rule coverage"
url: https://recursiveai.org/onehtml/docs/act-coverage/
description: "Generated by ActCoverageTests; do not edit by hand. To refresh it after a rule or an expectation changes, run the Validation tests with…"
version: "1.0.0"
source: https://github.com/recursive-ai-oss/onehtml-csharp/blob/cecf589eb9acfc9e1fbc529486dfef519a32c19c/docs/act-coverage.md
---

# ACT rule coverage

Generated by `ActCoverageTests`; do not edit by hand. To refresh it after a rule or an expectation changes, run the
Validation tests with `ONEHTML_UPDATE_DOCS=1`. The rule list and its status come from `Catalogue/Data/act-rules.json`
(see `catalogue.md`); the cases are the W3C test cases vendored under `testdata/act/`.

Columns: *Our rules* are the rules of this package that take the ACT rule as a source (or that the ACT harness runs
for it). The case columns count the vendored cases of the rule: *pass* the rule gave the expected outcome, *review*
the rule asks a person (needs-review) where ACT expects passed or failed, which is the honest answer for a judgement
rule, *n/a* cases a static check cannot judge (each is listed with its reason in the `testdata/act/*-expectations.tsv`
files), and *fail* cases where the rule disagrees with ACT. *Fail* is 0 everywhere; ACT wins disagreements.

- Approved: 37 rules, 37 implemented.
- Proposed: 50 rules, 36 implemented, 14 not automatable or not implemented (reason in the table).
- Deprecated: 7 rules, 4 implemented, 3 not automatable or not implemented (reason in the table).

| ACT id | Name | Status | Our rules | Cases | pass | review | n/a | fail |
|---|---|---|---|---|---|---|---|---|
| 09o5cg | Text has enhanced contrast | approved | `color-contrast-enhanced` | 29 | 25 | 0 | 4 | 0 |
| 0ssw9k | Scrollable content can be reached with sequential focus navigation | approved | `scrollable-region-focusable` | 10 | 6 | 0 | 4 | 0 |
| 0va7u6 | HTML images contain no text | approved | `image-of-text` | 14 | 2 | 12 | 0 | 0 |
| 23a2a8 | Image has non-empty accessible name | approved | `image-alt`, `role-img-alt`, `svg-img-alt` | 18 | 18 | 0 | 0 | 0 |
| 24afc2 | Important letter spacing in style attributes is wide enough | approved | `avoid-inline-spacing` | 16 | 16 | 0 | 0 | 0 |
| 2779a5 | HTML page has non-empty title | approved | `document-title` | 11 | 10 | 0 | 1 | 0 |
| 2t702h | Summary element has non-empty accessible name | approved | `summary-name` | 0 | | | | |
| 307n5z | Element with presentational children has no focusable content | approved | `nested-interactive` | 7 | 7 | 0 | 0 | 0 |
| 46ca7f | Element marked as decorative is not exposed | approved | `presentation-role-conflict` | 10 | 10 | 0 | 0 | 0 |
| 4e8ab6 | Element with role attribute has required states and properties | approved | `aria-required-attr` | 8 | 8 | 0 | 0 | 0 |
| 59796f | Image button has non-empty accessible name | approved | `input-image-alt` | 12 | 12 | 0 | 0 | 0 |
| 5f99a7 | ARIA attribute is defined in WAI-ARIA | approved | `aria-valid-attr` | 7 | 7 | 0 | 0 | 0 |
| 674b10 | Role attribute has valid value | approved | `aria-roles` | 10 | 10 | 0 | 0 | 0 |
| 6a7281 | ARIA state or property has valid value | approved | `aria-valid-attr-value` | 24 | 24 | 0 | 0 | 0 |
| 6cfa84 | Element with aria-hidden has no content in sequential focus navigation | approved | `aria-hidden-focus` | 14 | 13 | 0 | 1 | 0 |
| 73f2c2 | Autocomplete attribute has valid value | approved | `autocomplete-valid` | 20 | 20 | 0 | 0 | 0 |
| 78fd32 | Important line height in style attributes is wide enough | approved | `avoid-inline-spacing` | 21 | 14 | 0 | 7 | 0 |
| 7d6734 | SVG element with explicit role has non-empty accessible name | approved | `svg-img-alt` | 10 | 10 | 0 | 0 | 0 |
| 8fc3b6 | Object element rendering non-text content has non-empty accessible name | approved | `object-alt` | 14 | 14 | 0 | 0 | 0 |
| 97a4e1 | Button has non-empty accessible name | approved | `aria-command-name`, `button-name`, `input-button-name` | 17 | 17 | 0 | 0 | 0 |
| 9e45ec | Important word spacing in style attributes is wide enough | approved | `avoid-inline-spacing` | 16 | 16 | 0 | 0 | 0 |
| a25f45 | Headers attribute specified on a cell refers to cells in the same table element | approved | `td-headers-attr` | 17 | 16 | 0 | 1 | 0 |
| afw4f7 | Text has minimum contrast | approved | `color-contrast` | 28 | 24 | 0 | 4 | 0 |
| akn7bn | Iframe with interactive elements is not excluded from tab-order | approved | `frame-focusable-content` | 6 | 5 | 0 | 1 | 0 |
| b33eff | Orientation of the page is not restricted using CSS transforms | approved | `css-orientation-lock` | 10 | 10 | 0 | 0 | 0 |
| b4f0c3 | Meta viewport allows for zoom | approved | `meta-viewport` | 11 | 11 | 0 | 0 | 0 |
| b5c3f8 | HTML page has lang attribute | approved | `html-has-lang` | 7 | 5 | 0 | 2 | 0 |
| bc659a | Meta element has no refresh delay | approved | `meta-refresh` | 15 | 15 | 0 | 0 | 0 |
| bf051a | HTML page lang attribute has valid language tag | approved | `html-lang-valid` | 7 | 7 | 0 | 0 | 0 |
| bisz58 | Meta element has no refresh delay (no exception) | approved | `meta-refresh-no-exceptions` | 14 | 14 | 0 | 0 | 0 |
| c487ae | Link has non-empty accessible name | approved | `area-alt`, `aria-command-name`, `link-name` | 28 | 28 | 0 | 0 | 0 |
| c4a8a4 | HTML page title is descriptive | approved | `document-title-descriptive` | 6 | 1 | 5 | 0 | 0 |
| de46e4 | Element with lang attribute has valid language tag | approved | `valid-lang` | 19 | 19 | 0 | 0 | 0 |
| e086e5 | Form field has non-empty accessible name | approved | `aria-input-field-name`, `aria-toggle-field-name`, `label`, `select-name` | 17 | 17 | 0 | 0 | 0 |
| m6b1q3 | Menuitem has non-empty accessible name | approved | `aria-command-name` | 8 | 8 | 0 | 0 | 0 |
| oj04fd | Element in sequential focus order has visible focus | approved | `focus-visible-indicator` | 9 | 8 | 0 | 1 | 0 |
| qt1vmo | Image accessible name is descriptive | approved | `image-name-descriptive` | 16 | 10 | 6 | 0 | 0 |
| 047fe0 | Document has heading for non-repeated content | proposed | not automatable — its verdict depends on which content repeats across the pages of a site; one page cannot say (bypass answers the page-level question of cf77f2) | 14 | | | | |
| 1a02b0 | Audio and visuals of video element have transcript | proposed | `video-transcript` | 5 | 1 | 4 | 0 | 0 |
| 1ea59c | Video element visual content has audio description | proposed | `video-audio-description` | 7 | 1 | 6 | 0 | 0 |
| 1ec09b | Video element visual content has strict accessible alternative | proposed | `video-strict-alternative` | 7 | 1 | 6 | 0 | 0 |
| 2eb176 | Audio element content has transcript | proposed | `audio-caption` | 11 | 1 | 10 | 0 | 0 |
| 2ee8b8 | Visible label is part of accessible name | proposed | `label-content-name-mismatch` | 13 | 12 | 0 | 1 | 0 |
| 36b590 | Error message describes invalid form field value | proposed | not automatable — the error indicators of a form field (wording, icons, colour, position) are presentation with no markup that names them, so no element set can be offered for review | 9 | | | | |
| 3e12e1 | Block of repeated content is collapsible | proposed | not automatable — its verdict depends on which content repeats across pages and on what a script does to collapse it | 8 | | | | |
| 4b1c6c | Iframe elements with identical accessible names have equivalent purpose | proposed | `frame-title-unique` | 23 | 12 | 9 | 2 | 0 |
| 4c31df | Audio or video element that plays automatically has a control mechanism | proposed | `autoplay-audio-control` | 11 | 4 | 7 | 0 | 0 |
| 59br37 | Zoomed text node is not clipped with CSS overflow | proposed | not automatable — it needs the text laid out at 200% zoom to see whether an overflow clips it; there is no layout without a browser | 14 | | | | |
| 5c01ea | ARIA state or property is permitted | proposed | `aria-allowed-attr`, `aria-conditional-attr`, `aria-prohibited-attr` | 15 | 15 | 0 | 0 | 0 |
| 5effbb | Link in context is descriptive | proposed | `link-in-context-descriptive` | 18 | 3 | 15 | 0 | 0 |
| 7677a9 | Device motion based changes to the content can also be created from the user interface | proposed | not automatable — it depends on what a script does with device-motion events; scripts are inert text here | 6 | | | | |
| 80af7b | Focusable element has no keyboard trap | proposed | not automatable — it depends on running focus and key handlers; a keyboard trap is made by script | 16 | | | | |
| 80f0bf | Audio or video element avoids automatically playing audio | proposed | `no-autoplay-audio` | 8 | 3 | 5 | 0 | 0 |
| 9bd38c | Content has alternative for visual reference | proposed | not automatable — it asks whether instructions rely only on shape, size, position or colour; that is a judgement about the wording of the content, with no element to point at | 21 | | | | |
| a1b64e | Focusable element has no keyboard trap via standard navigation | proposed | not automatable — it depends on running focus and key handlers; a keyboard trap is made by script | 10 | | | | |
| aaa1bf | Audio or video element that plays automatically has no audio that lasts more than 3 seconds | proposed | `autoplay-audio-duration` | 7 | 2 | 5 | 0 | 0 |
| ab4d13 | Video element content is media alternative for text | proposed | `video-media-alternative` | 7 | 1 | 6 | 0 | 0 |
| afb423 | Audio element content is media alternative for text | proposed | `audio-caption` | 7 | 1 | 6 | 0 | 0 |
| aizyf1 | Link is descriptive | proposed | `link-descriptive` | 12 | 3 | 9 | 0 | 0 |
| b20e66 | Links with identical accessible names have equivalent purpose | proposed | `identical-links-same-purpose` | 21 | 6 | 14 | 1 | 0 |
| b40fd1 | Document has a landmark with non-repeated content | proposed | not automatable — its verdict depends on which content repeats across the pages of a site; one page cannot say | 8 | | | | |
| b49b2e | Heading is descriptive | proposed | `heading-descriptive` | 17 | 4 | 13 | 0 | 0 |
| bc4a75 | ARIA required owned elements | proposed | `aria-required-children` | 19 | 19 | 0 | 0 | 0 |
| c249d5 | Device motion based changes to the content can be disabled | proposed | not automatable — it depends on what a script does with device-motion events; scripts are inert text here | 5 | | | | |
| c3232f | Video element visual-only content has accessible alternative | proposed | `video-only-alternative` | 9 | 1 | 8 | 0 | 0 |
| c5a4ea | Video element visual content has accessible alternative | proposed | `video-visual-alternative` | 9 | 1 | 8 | 0 | 0 |
| cae760 | Iframe element has non-empty accessible name | proposed | `frame-title` | 10 | 10 | 0 | 0 | 0 |
| cc0f0a | Form field label is descriptive | proposed | `label-descriptive` | 14 | 2 | 11 | 1 | 0 |
| cf77f2 | Bypass Blocks of Repeated Content | proposed | `bypass` | 14 | 9 | 0 | 5 | 0 |
| d0f69e | Table header cell has assigned cells | proposed | `th-has-data-cells` | 16 | 16 | 0 | 0 | 0 |
| d7ba54 | Video element visual-only content has audio track alternative | proposed | `video-only-audio-track` | 5 | 1 | 4 | 0 | 0 |
| e7aa44 | Audio element content has text alternative | proposed | `audio-alternative` | 8 | 2 | 6 | 0 | 0 |
| e88epe | Image not in the accessibility tree is decorative | proposed | `image-decorative` | 20 | 7 | 10 | 3 | 0 |
| eac66b | Video element auditory content has accessible alternative | proposed | `video-caption` | 6 | 1 | 5 | 0 | 0 |
| ebe86a | Focusable element has no keyboard trap via non-standard navigation | proposed | not automatable — it depends on running focus and key handlers; a keyboard trap is made by script | 7 | | | | |
| ee13b5 | Video element visual-only content has transcript | proposed | `video-only-transcript` | 8 | 1 | 7 | 0 | 0 |
| efbfc7 | Text content that changes automatically can be paused, stopped or hidden | proposed | not automatable — it depends on timing, scripts and animation to know that text changes by itself | 11 | | | | |
| f51b46 | Video element auditory content has captions | proposed | `video-captions` | 8 | 1 | 7 | 0 | 0 |
| fd26cf | Video element visual-only content is media alternative for text | proposed | `video-only-media-alternative` | 7 | 1 | 6 | 0 | 0 |
| fd3a94 | Links with identical accessible names and same context serve equivalent purpose | proposed | `identical-links-same-context` | 19 | 8 | 11 | 0 | 0 |
| ff89c9 | ARIA required context role | proposed | `aria-required-parent` | 15 | 13 | 0 | 2 | 0 |
| ffbc54 | No keyboard shortcut uses only printable characters | proposed | not automatable — it depends on the key handlers a script installs | 10 | | | | |
| ffd0e9 | Heading has non-empty accessible name | proposed | `empty-heading` | 15 | 14 | 0 | 1 | 0 |
| kb1m8s | ARIA global properties not used where prohibited | proposed | `aria-prohibited-attr` | 0 | | | | |
| off6ek | HTML element language subtag matches language | proposed | `element-lang-matches-content` | 14 | 12 | 0 | 2 | 0 |
| ucwvc8 | HTML page language subtag matches default language | proposed | `html-lang-matches-content` | 15 | 14 | 0 | 1 | 0 |
| ye5d6e | Document has an instrument to move focus to non-repeated content | proposed | not automatable — its verdict depends on which content repeats across the pages of a site; one page cannot say | 12 | | | | |
| 3ea0c8 | Id attribute value is unique | deprecated | `duplicate-id`, `duplicate-id-active`, `duplicate-id-aria` | 10 | 10 | 0 | 0 | 0 |
| 5b7ae0 | HTML page lang and xml:lang attributes have matching values | deprecated | `html-xml-lang-mismatch` | 12 | 11 | 0 | 1 | 0 |
| 9eb3f6 | Image filename is accessible name for image | deprecated | not implemented — deprecated by the ACT task force; a file name is not an accessible name | 15 | | | | |
| ac7dc6 | Video element visual-only content has description track | deprecated | `video-only-description-track` | 5 | 1 | 4 | 0 | 0 |
| e6952f | Attribute is not duplicated | deprecated | not implemented — duplicate attributes are dropped by the parser; only a document parsed with errors recorded could report them | 10 | | | | |
| f196ce | Video element visual content has description track | deprecated | `video-description-track` | 5 | 1 | 4 | 0 | 0 |
| in6db8 | ARIA required ID references exist | deprecated | not implemented — deprecated by the ACT task force; the check lives on in aria-valid-attr-value (6a7281) | 0 | | | | |
