User agent reliability for VoiceOver Mac Screen reader compatibility

Screen Readers
Dec 12, 2023

Shows how well VoiceOver Mac supports ARIA and WCAG sufficient techniques.

Latest version tested

VoiceOver macOS 13.6 with Safari 16.6

  • All tests: 102 pass of 123 tests (83%)
  • ARIA tests: 39 pass of 45 tests (87%)
  • WCAG tests: 73 pass of 86 tests (85%)

Reliability trend

100%80%60%40%20%0%201470%201571%201671%201775%201876%201977%202083%202181%202283%202383%

Failing tests

 TestModeWhat the user hearsNotes
FailPage with xml:lang set on the html and p elementsReadingAct-if tay-bill. Ray-day-oh.Pronounced as English. Ignores xml:lang.
Failapplication/xhtml+xml page with mismatching lang and xml:lang on the html elementReadingGa-raj. Doo-ble. Damm. Un, zway, dray.Speech pronounced as lang=fr, but CSS matches :lang(de).
Failaudio with aria-label attributeReading Nothing Nothing voiced for audio - no indication it exists
Failaudio with aria-labelledby attributeReading Nothing Nothing voiced for audio - no indication it exists
Failaudio with title attributeReading Nothing Nothing voiced for audio - no indication it exists
Faila element placeholder link with no event handler or href attributeReadingPlaceholder text, clickableAnnounced as clickable, but no event handler so nothing happens when clicked
Failiframe with fallback contentReadingFrame oneMeaningless frame title read out.
FailInteractive iframe with role=presentation and negative tabindex and no accessible nameTabbing Nothing Skips over focusable link in iframe
Failabbr with titleReadingT L NABBR expansion ignored.
Failbutton containing img with title attributeReadingButtonReads "button" without saying what button does.
Failbutton containing img with title attributeTabbingButtonReads "button" without saying what button does.
Worseinput type=text with aria-describedby attributeTabbingFirst name, edit text, a bit of instructions for this field linked with aria describedby.ARIA-DESCRIBEDBY not read when tabbing
Worseinput type=text inside label with text before and after controlReadingEnter search text. Enter search text, and one more item, edit text. Blanks not allowed'And one more item' is read instead of the label text after the control.
Worseinput type=text inside label with text before and after controlTabbingEnter search text, and one more item, edit text'And one more item' is read instead of the label text after the control.
Failimg with figcaptionReadingViolet, taken on 12/11/2010, figure. One thousand, two hundred and thirty four PNG, image. Violet, taken on 12/11/2010. End of, Violet, taken on 12/11/2010, figure.Reads out meaningless filename and FIGCAPTION.
Failarea with aria-labelledby attributeReadingThis is alt text, image map. In, this is alt text, image map, 2 items, link, comma left underscore arrow HTM. Link, comma right underscore arrow HTMreads out filename instead of ARIA-LABELLEDBY
Failarea with aria-labelledby attributeTabbingLink, comma left underscore arrow HTM. Link, comma right underscore arrow HTMReads out filename instead of ARIA-LABELLEDBY
FailData table with role=columnheader headers but no thReading Nothing Ignores table completely.
FailData table with td headers attributeReading Table, 7 columns, 3 rows. Spans 2 rows, homework, column 1 of 7. Spans 3 columns, exams, column 2 of 7. Spans 3 columns, projects, column 5 of 7. Row 2 of 3, exams, one, column 2 of 7. Two column 3 of 7. Final column 4 of 7. Projects, one, column 5 of 7. Two column 6 of 7. Final column 7 of 7. Row 3 of 3, homework, fifteen percent, column 1 of 7. Exams and one, fifteen percent, column 2 of 7. Two, fifteen percent, column 3 of 7. Final, twenty percent, column 4 of 7. Projects and one, ten percent, column 5 of 7. Two, ten percent, column 6 of 7. Final, fifteen percent, column 7 of 7. Table incomprehensible - HEADERS relationships not announced correctly.
FailPDF18 Document with doc titleReadingSlash SR_PDF_doc_title.pdfVoices full URL. URL displayed in browser tab instead of title.
FailPDF16 Document default language set to FrenchReadingAct-if tay-billPronounced as English, document language ignored

Passing tests

 TestModeWhat the user hearsNotes
PassPage with lang set on the html and p elementsReadingAct-eef tab-le. Rah-di-oh.Pronounced as French and German.  
Passtext/html page with mismatching lang and xml:lang on the html elementReadingGa-raj. Doo-ble. Damm. Un, deux, trois.Speech pronounced as lang=fr, and CSS matches :lang(fr).  
PassMatch lang subtagsReadingDam-he. Dam-he. Dam-he.All pronounced as German.  
PassARIA role=headingHeadingHeading level 1, first level heading. Heading level 2, second level heading.  
PassHeading is img with altHeadingHeading level 2, second level alt, image.  
Betterapplet with title attributeReading Nothing Safari on macOS no longer supports applets, and does not render them on screen  
Betterapplet with fallback contentReadingFallback content for appletSafari on macOS no longer supports applets  
Betterapplet with aria-label attributeReadingAria label for applet, empty groupSafari on macOS no longer supports applets  
Betterapplet with aria-labelledby attributeReadingThis is ARIA-LABELLEDBY text, empty groupSafari on macOS no longer supports applets  
Passapplet inside figure with figcaption elementReadingFigure caption for applet, figure. Figure caption for applet. End of, figure caption for applet, figure.Safari on macOS no longer supports applets  
Betterembed with title attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Passembed inside figure with figcaptionReadingFigure caption for embed, figure. Figure caption for embed. End of, figure caption for embed, figure.  
Betterembed with aria-label attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Betterembed with aria-labelledby attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Betterobject with fallback contentReadingFallback content for object  
Betterobject with title attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Betterobject with aria-label attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Betterobject with aria-labelledby attributeReading Nothing Nothing displayed on screen and nothing voiced for object  
Bettervideo with aria-label attributeReadingVideo aria label, empty video playback.  
Bettervideo with aria-labelledby attributeReadingThis is ARIA-LABELLEDBY text, empty video playback.  
Bettervideo with title attributeReadingVideo title, empty video playback.  
Passa element placeholder link with no event handler or href attributeTabbing Nothing Skipped when tabbing, as expected  
Passiframe with fallback contentTabbingEntering frame, link, example hyperlink. Leaving frame.  
Passiframe with title attributeReadingThis is an IFRAME title, frame.IFRAME TITLE attribute read.  
Passiframe with title attributeTabbingEntering this is an IFRAME title frame, link, example hyperlink. Leaving this is an IFRAME title.  
PassInteractive iframe with role=presentation and no accessible nameReadingThis is an. Example hyperlink, link. In the target page.role=presentation makes frame seamless  
PassInteractive iframe with role=presentation and no accessible nameTabbingLink, example hyperlink  
PassInteractive iframe with role=presentation and negative tabindex and no accessible nameReadingThis is an. Example hyperlink, link. In the target page.role=presentation makes frame seamless  
Passbutton containing img with altReadingThis is image alt, button  
Passbutton containing img with altTabbingThis is image alt, button  
Passbutton containing img with aria-labelReadingThis is image aria label, button  
Passbutton containing img with aria-labelTabbingThis is image aria label, button  
Passbutton containing img with aria-labelledbyReadingThis is aria labelled by, button  
Passbutton containing img with aria-labelledbyTabbingThis is aria labelled by, button  
Passbutton with title containing img with null altReadingThis is button title, button  
Passbutton with title containing img with null altTabbingThis is button title, button  
Passbutton with aria-label containing img with null altReadingThis is button aria label, button  
Passbutton with aria-label containing img with null altTabbingThis is button aria label, button  
Passinput type=image with altReadingThis is image button alt text, button  
Passinput type=image with altTabbingThis is image button alt text, button  
Passinput type=image with title attributeReadingThis is image button title text, button  
Passinput type=image with title attributeTabbingThis is image button title text, button  
Passinput type=image with aria-label attributeReadingThis is image button aria label text, button  
Passinput type=image with aria-label attributeTabbingThis is image button aria label text, button  
Passinput type=image with aria-labelledby attributeReadingThis is image button aria-labelled by text, button  
Passinput type=image with aria-labelledby attributeTabbingThis is image button aria-labelled by text, button  
Passinput type=text with aria-describedby attributeReadingFirst name. First name, edit text, a bit of instructions for this field linked with aria describedby  
Passinput type=text with title attributeReadingEnter search text, edit text  
Passinput type=text with title attributeTabbingEnter search text, edit text  
Passinput type=text with aria-label attributeReadingEnter search text, edit text  
Passinput type=text with aria-label attributeTabbingEnter search text, edit text  
Passinput type=text with aria-labelledby attributeReadingEnter search text. Enter search text, edit text  
Passinput type=text with aria-labelledby attributeTabbingEnter search text, edit text  
Passinput type=text with label forReadingEnter search text. Enter search text, edit text  
Passinput type=text with label forTabbingEnter search text, edit text  
Passinput type=text inside label with text before controlReadingEnter search text. Enter search text, edit text  
Passinput type=text inside label with text before controlTabbingEnter search text, edit text  
Passinput type=text inside label with text after controlReadingEnter search text, edit text. Enter search text  
Passinput type=text inside label with text after controlTabbingEnter search text, edit text  
Passfieldset containing linksReadingLegend for enclosed links, group. Legend for enclosed links. Link, home. Link, about. Link, contact. End of, legend for enclosed links, group.  
Betterfieldset containing linksTabbingLink home, legend for enclosed links, legend for enclosed links, group. Link about, legend for enclosed links. Link contact, legend for enclosed links.Legend read out for every link.  
PassYes/No radio buttons inside fieldset elementReadingI agree to terms and conditions, group. I agree to terms and conditions. Yes, selected radio button, one of two. Yes. No, radio button, two of two. No. End of, I agree to terms and conditions, group. Sign me up to the newsletter, group. Sign me up to the newsletter. Yes, selected radio button, one of two. Yes. No, radio button, two of two. No. End of, sign me up to the newsletter, group.  
BetterYes/No radio buttons inside fieldset elementTabbingYes, selected radio button, one of two, I agree to terms and conditions, I agree to terms and conditions group. Yes, selected radio button, one of two, sign me up to the newsletter, sign me up to the newsletter group.  
Passimg with null altReading Nothing Ignored as expected  
Passimg with altReadingThis is alt text, image  
Passimg with titleReadingThis is title text, image  
Passimg with aria-labelReadingThis is an aria label, image  
Passimg with aria-labelledbyReadingThis is an aria labelled by, image. This is an aria labelled by  
Passarea and img with alt attributesReadingThis is alt text, image map. In, this is alt text, image map, 2 items, link, this is left alt text. Link, this is right alt text.  
Betterarea and img with alt attributesTabbingLink, this is left alt text. Link, this is right alt text  
Passarea with alt attribute and img with null altReadingLink, this is left alt text. Link, this is right alt text.  
Passarea with alt attribute and img with null altTabbingLink, this is left alt text. Link, this is right alt text.  
Passarea with title attributeReadingThis is alt text, image map. In, this is alt text, image map, 2 items, link, this is left title text. Link, this is right title text  
Betterarea with title attributeTabbingLink, this is left title text. Link, this is right title text  
Passarea with aria-label attributeReadingThis is alt text, image map. In, this is alt text, image map, 2 items, link, this is left aria label text. Link, this is right aria label text  
Betterarea with aria-label attributeTabbingLink, this is left aria label text. Link, this is right aria label text  
PassLink containing img with altReadingLink image, this is a link alt  
PassLink containing img with altTabbingLink image, this is a link alt  
PassLink containing img with titleReadingLink image, this is an image title  
PassLink containing img with titleTabbingLink image, this is an image title  
BetterClick Here link with title attributeReadingLink, click here, this is a link title  
BetterClick Here link with title attributeTabbingLink, click here, this is a link title  
PassLink text replaced by aria-label attributeReadingLink, this is an aria label  
PassLink text replaced by aria-label attributeTabbingLink, this is an aria label  
PassLink text replaced by aria-labelledby attributeReadingLink, this is an aria labelled by. This is an aria labelled by  
PassLink text replaced by aria-labelledby attributeTabbingLink, this is an aria labelled  
BetterClick Here link with aria-describedby attributeReadingLink, click here, this is an aria described by. This is an aria described by  
BetterClick Here link with aria-describedby attributeTabbingLink, click here, this is an aria described by.  
PassLayout table with single cellReadingThis is some text.Treated as a layout table.  
PassLayout table with role=presentationReadingExample. Navigation. Links. Content.Table treated as layout table - not announced as table.  
BetterData table with role=gridReadingTable, 2 columns, 2 rows. Morning, column 1 of 2. Afternoon, column 2 of 2. Row 2 of 2, morning, free, column 1 of 2. Afternoon, busy, column 2 of 2.  
PassData table with role=tableReadingTable, 1 column, 1 row. This is some text, column 1 of 1.  
BetterData table with summary and thReadingTable two columns, two rows, data table summary. Morning, column one of two. Afternoon, column two of two. Row two of two, morning, free, column one of two. Afternoon, busy, column two of two.  
PassData table with caption and thReadingData table caption, table, two columns, two rows. Morning, column one of two. Afternoon, column two of two. Row two of two morning, free, column one of two. Afternoon, busy, column two of two.  
PassData table with th cell headersReadingTable, 2 columns, 2 rows. Morning, column 1 of 2. Afternoon, column 2 of 2. Row 2 of 2, morning, free, column 1 of 2. Afternoon, busy, column 2 of 2.  
BetterData table with th scope on cell headersReading Contact information, table, 5 columns, 4 rows. Blank, column 1 of 5. Name, column 2 of 5. Phone number, column 3 of 5. Fax number, column 4 of 5. City, column 5 of 5. Row 2 of 4, one, column 1 of 5. Name, Joel Garner, column 2 of 5. Phone, 412 212 5421, column 3 of 5. Fax, 412 212 5400, column 4 of 5. City, Pittsburgh, column 5 of 5. Row 3 of 4, two, column 1 of 5. Name, Clive Lloyd, column 2 of 5. Phone, 410 306 1420, column 3 of 5. Fax, 410 306 5400, column 4 of 5. City, Baltimore, column 5 of 5.  
PassPDF9 Document with headingsReadingHeading level 1, Heading 1. Heading level 2, heading 1.2.  
PassPDF1 Image with alt textReadingThis is alt text, image  
PassPDF4 Decorative image marked as artifactReading Nothing Image ignored as expected  
PassPDF19 Phrase language set to GermanReadingRah-di-ohPronounced as German  
BetterPDF6 Table with header markupReadingTable, no selection. Morning, column 1, row 1. Afternoon, column 2, row 1. Morning, free. Afternoon, busy.  
BetterPDF6 Table with header markup and alt textReadingTable, no selection. Morning, column 1, row 1. Afternoon, column 2, row 1. Morning, free. Afternoon, busy.