Problem/Motivation
Elements that use .visually-hidden and .focusable classes (such as the skiplink) are not read when using the VoiceOver screenreader in iOS (iPhone or iPad) or in Chrome on a Mac.
For an easy demo of this problem, try listening to the skiplinks here on d.o with VoiceOver either on an iOS device or in Chrome on a Mac. Even though d.o is using D7 and the classes have different names, the styles are the same as in D8.
This problem doesn’t appear in the Seven theme because it sets the position to absolute when focusable elements are focused.
Proposed resolution
Using the HTML5 Boilerplate version of the visually-hidden and focusable styles and removing position: static from the focusable styles fixed this problem for me.
Required Tests
Let's make sure there are no regressions in these other AT:
- JAWS - Untested
- NVDA - Untested
- VoiceOver - Untested
- ChromeVox - Untested
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | 2464595-nr-bot.txt | 144 bytes | needs-review-queue-bot |
| #22 | 2464595-22.patch | 793 bytes | Phil Wolstenholme |
Comments
Comment #1
mgiffordHTML Boilerplate also has
position: static;in it, so is this a new pattern?skip-link.css has the focusable element defined, but it isn't static, but rather
position: static. I'm just trying to get some clarification here:.skip-link.visually-hidden.focusable:focus {
position: absolute !important;
}
Which version of iOS is this?
Comment #2
mgiffordNeeds re-roll.
Comment #3
devtherock commentedRe-rolled with 8.2.x-dev
Comment #4
mgiffordThanks for the re-roll. I'd argue thought hat this should stay in 8.0 rather than bumping it up to 8.2.
Comment #5
andrewmacpherson commentedIf this is a bug fix, presumably it's still a candidate for an 8.1.x maintenance release
Comment #6
andrewmacpherson commentedAfter the patch in #3, the rule for
.visually-hiddenlooks like this:Feedback:
positionproperty is declared twice; this needs clean-up.!importantkeyword is used the first timepositionis declared, but not the second time. What's the intention - do we keep the important keyword? The (existing) comment says we want the important keyword to avoid accidental overrides.Comment #7
imalabyaUpdated with the above changes.
Comment #8
mgiffordWe need to have some testing in AT before we can mark this RTBC.
Comment #9
andrewmacpherson commentedAgreed, it's about specific browser/AT combinations. Do we know if this problem is documented elsewhere, perhaps in HTML5 boilerplate's issue history?
I don't have ready access to a Mac or iOS device. I can test in ChromeVox and NVDA, but that only guards against regressions. We need the Mac + iOS tests to confirm it actually makes things better.
Tagging in case someone can pick it up at the New Orleans sprints.
Failing that I'll go and bother some Mac owners at a local tech meet-up ;-)
Comment #10
john cook commentedI've just tried this with voiceover on both iPhone (safari and chrome) and Mac (chrome) using 8.2.x without applying the patch and the skip links are read on both devices.
Has the problem been independently fixed in Bartek and Stark?
Comment #11
mgiffordLooking at the patch and knowing the history of this issue, I wouldn't think that there were any changes to Bartik, Classy, Seven Stable or Stark.
But we can check if
.visually-hiddenor .visually-hidden.focusable:active/.visually-hidden.focusable:focusin core/modules/system/css/components/hidden.module.css is over-ruled in the other Core themes we should be fine.Unfortunately it seems to be, so yes this will have to be checked on other themes:
$ grep -ir visually-hidden * | grep css
bartik/css/components/header.css: /* @extend .visually-hidden */
bartik/css/components/skip-link.css:.skip-link.visually-hidden.focusable:focus {
seven/css/components/skip-link.css:.skip-link.visually-hidden.focusable:focus {
stable/css/system/components/hidden.module.css:.visually-hidden {
stable/css/system/components/hidden.module.css: * The .focusable class extends the .visually-hidden class to allow
stable/css/system/components/hidden.module.css:.visually-hidden.focusable:active,
stable/css/system/components/hidden.module.css:.visually-hidden.focusable:focus {
Comment #15
mgiffordComment #16
droplet commentedI closed mine duplicated issue. COPY MY WORD:
FYI: There's an issue thread for more better accessibility on this CLASS. Probably we should update it together at once.
[macOS - VoiceOver / Chrome announcing visually hidden text out of order]
https://github.com/h5bp/html5-boilerplate/issues/1985
Comment #19
andrewmacpherson commentedchanging issue tag to a more accurate name, got some others with this tag already
Comment #22
Phil Wolstenholme commentedThe earlier patches fail to apply, so I had a go at updating this, and it's such a rabbit hole!
Since we copied HTML5 Boilerplate's lead I started there, their approach has changed since Drupal copied it I believe, but there's also this issue with their approach resulting in content being updated in the wrong order: https://github.com/h5bp/main.css/issues/12. I'm not sure if their updated approach fixes this specific Voiceover issue or not?
Someone from the GOV.UK development team in the United Kingdom made a big comparison of hiding text methods, but it includes lots of non-CSS approaches so is only partially relevant: https://gist.github.com/nickcolley/19b80ed24d0364cfd3afd3b1b49c4014
Bootstrap have recently released v5 and they have updated their approach here: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden... ………
The list goes on!
I eventually gave up and decided to stick with whatever HTML5 Boilerplate is using, in the spirit of Drupal's original decision.
Attached is a patch that brings the Drupal implementation inline with the latest HTML5 Boilerplate implementation from https://github.com/h5bp/main.css/blob/master/src/_helpers.css#L14-L51.
There is still the issue of themes having their own implementations - this patch just targets
core/themes/stable/css/system/components/hidden.module.css.Comment #23
andypostneeds more eyes on it
Comment #26
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #27
mgiffordWe really should fix this!
This could possibly fall under a few SC, but I'm putting it under https://www.w3.org/WAI/WCAG21/Understanding/name-role-value
Comment #29
ricksta commentedI'm not experiencing any problems with Apple VoiceOver. Skip link is being read.
MacBook Pro Sonoma 14.1
Drupal version 11.0-dev
Private windows opened in:
Google Chrome: Version 119.0.6045.199
Firefox: 120.0.1 (for this I used Chris Pederick's Web Developer tools simulator for iOS 12/13, Pro max IOS 114.6)
Comment #30
saurav-drupal-dev commentedtried to reproduce it but as comment #29 mentioned and for me also the voice over issue i am not facing it tried on chrome and safari for ios and for desktop too.
Comment #32
kentr commentedThis might be outdated, per #29 and #30.
IIRC, I haven't experienced this recently with VO on MacOS, but I will double-check.
Comment #33
kentr commentedI'm not experiencing the problem with VoiceOver on:
mainbranch, Microsoft Edge, MacOS 14.8.7. Edge is based on Chromium, as is Chrome.11.4.0-beta1, physical iPhone 16, iOS 26.5Tested:
Feel free to reopen if new cases are found.