vocab.design

accessibility · platform-registers

Accessibility trait

also called accessibilityTraits (uikit), UIAccessibilityTraits (uikit), accessibilityRole (community), mobile role (community)

The platform flag on a native view that says what it is and how it behaves, the mobile counterpart to a role plus a state, and the thing a custom control has to set by hand.

On the web, what a control is comes from the element or from an ARIA role, and what state it is in comes from separate attributes. Native platforms fold both into one list. UIKit calls that list accessibilityTraits: an option set a view carries, holding values like .button, .header, .link, .image, .adjustable, .selected and .notEnabled. Jetpack Compose spells the kind half as a semantics Role, matched in tests as SemanticsProperties.Role. Either way the trait is not the accessible name: the name says which thing this is, the trait says what kind of thing it is and what state it is in. Name role value is the same triple written for the web.

Traits are what an announcement is made of. Deque’s walk through the iOS set is specific about it: .button adds the word button after the label, .link adds the word link, .selected reads out as selected, .notEnabled reads out as dimmed, and .header both reads as header and puts the view in VoiceOver’s rotor, which is how a reader jumps between sections instead of swiping through every element in one. Setting a trait is therefore a claim, not decoration, and a wrong claim costs more than a missing one: a .header on something that is not a section start fills the rotor with destinations that lead nowhere.

The failure this word exists for is a custom control that starts with none. A view drawn by hand looks right, answers taps, and announces as plain static text, so a screen reader user moving by explore by touch hears a label with nothing after it: no word saying it can be activated, no word saying it is the one currently on. The platform infers traits for its own controls and infers nothing for yours, which is why every custom control is a place to check. It is the same gap the web has when a div is wired up as a button without semantic HTML or a role behind it.

A trait is about one element. Its round mate, accessibility grouping, is about how many elements there are: a trait says what this element is announced as, grouping says which elements are announced as one. The two are set on the same view and answer different questions, and a card with the right traits on every child can still be four stops that mean nothing apart.

Which word?

If you wantsay
a custom native control announces as plain textaccessibility trait
auditing whether a custom control is really a controlname, role, value
renaming what a widget calls itself out loudrole description

Related

See also: Semantic HTML

Sources