Skip to main content

Accessibility Audit (WCAG 2.2)

Every form has a built-in accessibility audit that checks the markup for WCAG 2.1/2.2 issues affecting screen reader and keyboard users. The audit is a static analysis of the form's HTML -- it runs locally with no network calls and is cheap enough to run on every save.

Class: Core_Forms\Admin\AccessibilityTester Source: src/admin/class-accessibility-tester.php

The Audit Panel

Open a form and switch to the Fields tab. The WCAG 2.2 audit panel sits above the builder and shows:

  • A summary line ("No automated issues found." or "N issues found.").
  • The first 10 issues, each with a rule code and a plain-language message.
  • Run audit -- re-checks the current saved markup on demand.
  • Fix safe issues -- applies automatic repairs (disabled when there are no issues).

The audit also runs automatically whenever the form is saved (visual builder, code editor, or REST), and the result is cached in the _cf_a11y_report post meta. The forms list screen shows a per-form Accessibility column based on the same report.

What the Audit Checks

Rule What it flags
missing_label A control with no <label for>, wrapping <label>, aria-label, or aria-labelledby
group_no_fieldset Radio/checkbox groups (2+ inputs sharing a name) not wrapped in a <fieldset> with a <legend>
missing_aria_required Required fields missing aria-required="true" (reported when 3 or more)
select_no_placeholder A required <select> whose first option is not an empty placeholder
button_no_text / submit_no_value Submit buttons with no visible text or value
broken_describedby aria-describedby pointing at an id that doesn't exist
image_no_alt <img> elements without an alt attribute
iframe_no_title <iframe> elements without a title
missing_autocomplete Common email/tel/name fields without autocomplete tokens (reported when 2 or more)
empty_lang Elements with an empty lang attribute

Hidden, submit, button, reset, and image inputs are skipped by the label check, and a single standalone checkbox (for example a consent box) does not require a fieldset.

Fix Safe Issues

Fix safe issues applies deterministic repairs to the form markup, saves it, and re-runs the audit:

  • Adds a missing id to each visible control (derived from its name, deduplicated).
  • Inserts a <label for> before any unlabelled control, using a humanized version of the field name.
  • Adds aria-required="true" to fields marked required.
  • Adds autocomplete to common fields by name: email, phone/tel, first_name, last_name, name.
  • Gives empty buttons an accessible name (aria-label="Submit form").
  • Adds empty alt="" to images with no alt attribute (treating them as decorative).
  • Adds a title ("Embedded content") to untitled iframes.

It never renames fields and never changes submitted values -- name attributes, field types, and options are untouched, so existing submissions, actions, and integrations keep working.

Issues that require a judgment call are reported but not auto-fixed: wrapping option groups in <fieldset>/<legend>, writing descriptive button text, repairing broken aria-describedby targets, and adding a placeholder option to required selects. Fix those in the visual builder or the code editor.

Notes

  • Both audit and fix require the edit_forms capability and are protected by a per-form nonce.
  • After a fix, the page reloads so the builder shows the repaired markup.
  • The generated labels are simple starting points (e.g. first_name becomes "First Name"); reword them to match your form's tone.
  • A parse_error result means the markup couldn't be parsed at all -- fix the invalid HTML in the code editor first.