User agent reliability for VoiceOver iOS Screen reader compatibility
Screen Readers
Dec 12, 2023
Shows how well VoiceOver iOS supports ARIA and WCAG sufficient techniques.
Latest version tested
VoiceOver iOS 16.6 with Safari iOS 16.6
- All tests: 59 pass of 78 tests (76%)
- ARIA tests: 25 pass of 31 tests (81%)
- WCAG tests: 39 pass of 52 tests (75%)
Reliability trend
Failing tests
Test | Mode | What the user hears | Notes | |
---|---|---|---|---|
Page with xml:lang set on the html and p elements | Touch | Act-if tay-bill. Ray-day-oh. | Pronounced as English. Ignores xml:lang. | |
application/xhtml+xml page with mismatching lang and xml:lang on the html element | Touch | Ga-raj. Doo-ble. Damm. Un, zway, dray. | Speech pronounced as lang=fr, but CSS matches :lang(de) and German CSS content pronounced as French. | |
audio with aria-label attribute | Touch | Nothing | Nothing voiced for audio - no indication it exists | |
audio with aria-labelledby attribute | Touch | Nothing | Nothing voiced for audio - no indication it exists | |
audio with title attribute | Touch | Nothing | Nothing voiced for audio - no indication it exists | |
abbr with title | Touch | T L N | ABBR expansion ignored. | |
button containing img with title attribute | Touch | Button | Reads "button" without saying what button does. | |
fieldset containing links | Touch | Legend for enclosed links, form start. Home, link. About, link. Contact, link end, legend for enclosed links, form end. | The fieldset is announced as a form, but contains no form controls. | |
img with figcaption | Touch | One thousand, two hundred and thirty four PNG, image, test image. Violet, taken on twelve slash eleven slash two thousand and ten. | Reads out meaningless filename, then FIGCAPTION. | |
area and img with alt attributes | Touch | This is alt text. (This is left alt text, link. This is right alt text, link) | Very hard to find AREA links because image map links are not announced when reading. It is possible to find them by minesweeping, or using the Next Link gesture, but there are no audible cues to tell the user they're missing links. | |
area with title attribute | Touch | This is alt text. (This is left title text, link. This is right title text, link.) | Very hard to find AREA links because image map links are not announced when reading. It is possible to find them by minesweeping, or using the Next Link gesture, but there are no audible cues to tell the user they're missing links. | |
area with aria-label attribute | Touch | This is alt text. (This is left ARIA label text, link. This is right ARIA label text, link.) | Very hard to find AREA links because image map links are not announced when reading. It is possible to find them by minesweeping, but there are no audible cues to tell the user they're missing links. | |
area with aria-labelledby attribute | Touch | This is alt text. (Left arrow HTM, link. Right arrow HTM, link.) | Very hard to find AREA links because image map links are not announced when reading. URLs read out instead of ARIA-LABELLEDBY when Next Link gesture is used. | |
Data table with role=grid | Reading | Morning, row 1, column 1, table start, 2 rows 2 columns. Afternoon, row 1 column 2. Free, row 2 column 1. Busy, row 2 column 2. Table end, end, end. | Voiced as table, but no headers read | |
Data table with summary and th | Reading | Morning, row header, column header, row 1, column 1, table start, 2 rows 2 columns. Afternoon, column header, row 1 column 2. Morning, free, row 2 column 1. Afternoon, busy, row 2 column 2, table end, end, end. | Summary not read out | |
Data table with caption and th | Touch | Data table caption, row -90020023372036854775808, table start, 2 rows 2 columns. Morning, row header, column header, row 1 column 1. Afternoon, column header, row 1 column 2. Morning, free, row 2 column 1. Afternoon, busy, row 2 column 2, table end, end, data table caption, end. | Meaningless row number read out for table caption. | |
Data table with role=columnheader headers but no th | Reading | Morning, afternoon. Free, busy. | Table treated as layout table - not announced as table, and no headers read. | |
Data table with th scope on cell headers | Touch | Contact information, row -90020023372036854775808, table start, 4 rows, 5 columns. Name, row header, row 1 column 2. Phone hash symbol, row 1 column 3. Fax hash symbol, row 1 column 4. City, row 1 column 5. One, row 2 column 1. Joel Garner, row 2 column 2. 412 212 5421, row 2 column 3. 412 212 5400, row 2 column 4. Pittsburgh, row 2 column 5. Two, row 3 column 1. Clive Lloyd, row 3 column 2. 410 306 1420, row 3 column 3. 410 306 5400, row 3 column 4. Baltimore, row 3 column 5. | Incomprehensible - doesn't read any cell headings, and reads out meaningless row number for caption. | |
Data table with td headers attribute | Reading | Homework, row header, column header, spans 2 rows, row 1 column 1, table start, 3 rows 7 columns. Exams, column header, spans 3 columns, row 1 column 2. Projects, column header, spans 3 columns, row 1 column 5. Exams, one, row 2 column 2. Exams, two, row 2 column 3. Exams, final, row 2 column 4. Projects, one, row 2 column 5. Projects, two, row 2 column 6. Projects, final, row 2 column 7. Homework, fifteen percent, row 3 column 1. Exams, fifteen percent, row 3 column 2. Exams, fifteen percent, row 3 column 3. Exams, twenty percent, row 3 column 4. Projects, ten percent, row 3 column 5. Projects, ten percent, row 3 column 6. Projects, fifteen percent, row 3 column 7, table end, end, end. | Table incomprehensible - only first header in HEADERS list is voiced. |
Passing tests
Test | Mode | What the user hears | Notes | |
---|---|---|---|---|
Page with lang set on the html and p elements | Touch | Act-eef tab-le. Rah-di-oh. | Pronounced as French and German. | |
text/html page with mismatching lang and xml:lang on the html element | Touch | Ga-raj. Doo-ble. Damm. Un, deux, trois. | Speech pronounced as lang=fr, and CSS matches :lang(fr). | |
Match lang subtags | Touch | Dam-he. Dam-he. Dam-he. | All pronounced as German. | |
ARIA role=heading | Touch | First level heading, heading level 1. Second level heading, heading level 2 | ||
Heading is img with alt | Touch | Second level alt, heading level 2, image, test image. | Reads out text in image as well as alt text. | |
applet with title attribute | Touch | Nothing | iOS does not support applets, and does not render them on screen | |
applet with fallback content | Touch | Fallback content for applet | iOS does not support applets | |
applet with aria-label attribute | Touch | Nothing | iOS does not support applets, and does not render them on screen | |
applet with aria-labelledby attribute | Touch | Nothing | iOS does not support applets, and does not render them on screen | |
applet inside figure with figcaption element | Touch | Figure caption for applet | ||
embed with title attribute | Touch | Title text for embed | ||
embed inside figure with figcaption | Touch | Figure caption for embed | ||
embed with aria-label attribute | Touch | Aria label for embed | ||
embed with aria-labelledby attribute | Touch | This is ARIA-LABELLEDBY text | ||
object with fallback content | Touch | Fallback content for object | ||
object with title attribute | Touch | Title for object | ||
object with aria-label attribute | Touch | Aria label for object | ||
object with aria-labelledby attribute | Touch | This is ARIA-LABELLEDBY text. | ||
video with aria-label attribute | Touch | Video aria label, 5 seconds, video playback, end article, elapsed time 0 seconds, double-tap to play or pause. | ||
video with aria-labelledby attribute | Touch | This is ARIA-LABELLEDBY text, 5 seconds, video playback, end article, elapsed time 0 seconds, double-tap to play or pause. | ||
video with title attribute | Touch | Video title, 5 seconds, video playback, end article, elapsed time 0 seconds, double-tap to play or pause. | ||
iframe with fallback content | Touch | This is an. Example hyperlink, link. In the target page. | Fallback content is ignored | |
iframe with title attribute | Touch | This is an. Example hyperlink, link. In the target page. | ||
Interactive iframe with role=presentation and no accessible name | Touch | This is an. Example hyperlink, link. In the target page. | ||
Interactive iframe with role=presentation and negative tabindex and no accessible name | Touch | This is an. Example hyperlink, link. In the target page. | ||
button containing img with alt | Touch | This is image alt, button | ||
button containing img with aria-label | Touch | This is image aria label, button | ||
button containing img with aria-labelledby | Touch | This is aria labelled by, button | ||
button with title containing img with null alt | Touch | This is button title, button | ||
button with aria-label containing img with null alt | Touch | This is button aria label, button | ||
input type=image with alt | Touch | This is image button alt text, button | ||
input type=image with title attribute | Touch | This is image button title text, button | ||
input type=image with aria-label attribute | Touch | This is image button aria label text, button | ||
input type=image with aria-labelledby attribute | Touch | This is image button aria-labelled by text, button | ||
input type=text with aria-describedby attribute | Touch | First name, text field, a bit of instructions for this field linked with aria describedby | ||
input type=text with title attribute | Touch | Enter search text, text field | ||
input type=text with aria-label attribute | Touch | Enter search text, text field | ||
input type=text with aria-labelledby attribute | Touch | Enter search text, text field, double tap to edit | ||
input type=text with label for | Touch | Enter search text, text field, end article, double tap to edit | ||
input type=text inside label with text before control | Touch | Enter search text, text field, end article, double tap to edit | ||
input type=text inside label with text after control | Touch | Enter search text, text field, double tap to edit | ||
input type=text inside label with text before and after control | Touch | Enter search text blanks not allowed, text field, double tap to edit | ||
Yes/No radio buttons inside fieldset element | Touch | I agree to terms and conditions, form start. Yes, radio button, ticked, one of two. No, radio button, unticked, two of two. Sign me up to the newsletter, form start. Yes, radio button, ticked, one of two. No, radio button, unticked, two of two. | ||
img with null alt | Touch | Nothing | Ignored as expected | |
img with alt | Touch | This is alt text, image, test image | Text in image captured via OCR | |
img with title | Touch | This is title text, image, test image | ||
img with aria-label | Touch | This is an aria label, image, test image | ||
img with aria-labelledby | Touch | This is an aria labelled by, image, test image | ||
area with alt attribute and img with null alt | Touch | This is left alt text, link. This is right alt text, link. | Link role only announced when reading if owner IMG has null alt. | |
Link containing img with alt | Touch | This is a link alt, link image | ||
Link containing img with title | Touch | This is an image title, link image | ||
Click Here link with title attribute | Touch | Click here, link, this is a link title | ||
Link text replaced by aria-label attribute | Touch | This is an aria label, link | ||
Link text replaced by aria-labelledby attribute | Touch | This is an aria labelled by, link | ||
Click Here link with aria-describedby attribute | Touch | Click here, link, this is an aria described by | ||
Layout table with single cell | Reading | This is some text. | Treated as a layout table. | |
Layout table with role=presentation | Reading | Example, Navigation. Links, Content. | Table treated as layout table - not announced as table. | |
Data table with role=table | Reading | This is some text. Table start, end. | Treated as a data table. | |
Data table with th cell headers | Reading | Morning, row header, column header, row 1 column 1, table start, 2 rows 2 columns. Afternoon, column header, row 1 column 2. Morning, free, row 2 column 1. Afternoon, busy, row 2 column 2, table end, end, end. | Column headers are not read by the Read Screen gesture, but are read by the Read Item gesture. |