A WCAG Audit Fails the Custom Checkbox Form
A public benefits portal is built in ODC and must meet WCAG 2.1 AA. The application form has 14 fields, including a custom checkbox group and a date picker. To match the brand, the designer removed all focus outlines and rebuilt checkboxes as a clickable Container with an Icon; the native checkbox is hidden with display: none. Each field's only visible label is a placeholder such as 'Enter your ID'. Validation errors appear as red text under the field with no icon. The submit control is a Link styled to look like a button. On a phone, the checkbox hit area measures 24x24 px. A screen-reader audit reports that fields are announced as 'edit text' with no accessible name, keyboard Tab skips the checkboxes, and errors are not announced.
1. List the failures by WCAG area and map each to the OutSystems widget or property you would change.
Read the worked answer
The failures span names, roles, keyboard access, focus visible and error identification. Fields announced as 'edit text' with no name mean the Input widgets have no associated label: use the Input's Label property instead of relying on a placeholder. The placeholder disappears on input and is not an accessible name.
The checkbox group fails because the native Input is hidden with display: none, which removes it from the accessibility tree and from tab order. Keep a real Checkbox Input in the DOM and style it, or use the OutSystems UI Checkbox pattern, rather than a clickable Container with an Icon. The submit Link fails because it has link role, not button role, and does not respond to Space; replace it with a Button widget. Red-text-only errors fail the 'use of colour' and 'error identification' criteria; add text, an icon and a programmatic association. The 24x24 px target fails the target-size expectation.
2. How would you restore a visible focus indicator and a 44x44 px target without losing the brand look?
Read the worked answer
Use :focus-visible rather than removing focus entirely. Keep the custom visual style and add an outline that has at least 3:1 contrast against the adjacent background, for example a 2 px solid ring plus a 2 px offset. Do not use outline: none without a replacement. Test with keyboard only, because a mouse click may not show the ring while Tab must.
For the checkbox, do not shrink the hit area to the icon. Keep a 44x44 px tappable Container and center the 24x24 px visual inside it so the brand size is preserved. The native checkbox can be visually hidden with a clip-path or opacity technique that keeps it focusable, but the simplest robust approach in OutSystems is to use the built-in Checkbox and style its label and box through the theme. Verify the target with a ruler or devtools box model, not by eye.
3. How would you make validation errors programmatically associated and announced?
Read the worked answer
Each invalid field needs three things: an accessible name from its Label, an invalid state such as aria-invalid=true, and an association to the error text via aria-describedby pointing at the error element's id. In OutSystems, bind the error message to a Container with a stable id and add the aria-describedby value through the Input's Extended Properties. Do not put the error only in a tooltip or only in red text.
For screen-reader announcement, render an error summary at the top of the form with role=alert or aria-live=assertive after a failed submit, listing the fields and linking to them. The summary should receive focus or be announced when it appears. Keep the per-field text too, so the user hears the error when returning to the field. Test with at least one screen reader and keyboard-only navigation, because an aria-describedby that points to an empty element passes a static checker but fails in use.