Skip to content

bug: ion-input-otp - inputs are named "Input n of m" only, host ARIA is not forwarded, error text cannot be associated, focus outline removed #31619

Open

Description

@mrambow

Prerequisites

Ionic Framework Version

v8.x, v9.x

Current Behavior

ion-input-otp renders its native <input> elements with a fixed, English accessible name
("Input 1 of 6" ... "Input 6 of 6"). An aria-label set on the host is forwarded to the group
only, not to the inputs, so a screen reader user never hears what the inputs are for (e.g. "PIN").
An error message rendered next to the component cannot be associated with the inputs: there is
no way to set aria-describedby / aria-errormessage or aria-invalid on the native inputs.
The component also removes the focus outline (outline: none, specificity 0,4,0), so keyboard
focus is visible only through the border colour, and the default border colour is set in a rule
with specificity 0,2,0 that can only be overridden via --ion-color-step-300, not via
--border-color.

Measured with TalkBack (Android 14, Capacitor 8): "Passwort. 1 Zeichen. Input 5 of 6".
Verified on Ionic 9.0.8 and 8.8.5 with identical results (Chrome headless, accessibility tree, after
tabbing into the component): the host aria-label, aria-describedby and aria-invalid move to the
role="group" wrapper (group: name "PIN", description = error text, invalid=true); the native inputs
keep the name "Input 1 of 6" with no description and invalid=false; the focused input has
outline: none, only the border colour changes. A previous attempt to add helperText/errorText
(#30698) was closed without merge.

Expected Behavior

  • A way to label the inputs (translated, e.g. "PIN, Ziffer 1 von 6"), for example an
    inputLabel function or forwarding aria-label with the index appended.
  • aria-describedby / aria-invalid forwarded to the native inputs so an error message can be
    associated.
  • A visible focus indicator with at least 3:1 contrast, or a --focus-outline CSS variable.

Steps to Reproduce

  1. Place <ion-input-otp length="6" aria-label="PIN"></ion-input-otp> and a <p id="err"> error
    message next to it.
  2. Inspect the accessibility tree: inputs are named "Input 1 of 6" ...; aria-label sits on the group.
  3. Try to associate #err with the inputs - no API.
  4. Tab into the component: no outline, only the border colour changes.

Code Reproduction URL

https://github.com/mrambow/starterApp/blob/a11y-repros/core-repros/otp.html - single HTML file, no build,
loads @ionic/core from jsDelivr; ?v=8.8.5 switches the version.
Live: https://raw.githack.com/mrambow/starterApp/a11y-repros/core-repros/otp.html

Code Reproduction URL

https://github.com/mrambow/starterApp/blob/a11y-repros/core-repros/otp.html

Ionic Info

@ionic/core 9.0.8 and 8.8.5, plain HTML. Found in: Ionic 8.8.5, Angular 21, Capacitor 8;
Android 14 WebView (TalkBack), iOS 26.

Additional Information

No response

Activity

  1. added
    type: buga confirmed bug report
    and removed on Oct 23, 2026
  2. added theissue type on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: buga confirmed bug report

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions