Problem/Motivation
The Entity Display forms ("manage display" and "manage form display") have a visually-hidden button:
<input class="visually-hidden button js-form-submit form-submit" data-drupal-selector="edit-refresh" id="edit-refresh" name="op" value="Refresh" type="submit">
This button is triggered programatically as part of Field UI's ajax behaviours. It seems this button is NOT intended to be activated by human users, hence the visually-hidden class. Mouse/pointer users cannot operate this button, because it has zero height and width.
However, this button is still in the keyboard tabbing order, and can be activated by a keyboard user. The visually-hidden class means the focused button isn't perceivable though, which is a failure of WCAG 2.4.7 Focus Visible. It acts as a confusing extra tab-stop for keyboard users, who can activate it by accident (though doing so seems to be harmless).
Proposed resolution
Hide the button from all users, not just sighted mouse/pointer users.
Possible Approaches:
The most reliable way to hide the button from all user is with display: none. This will hide it from screen readers, and remove it from the tabbing order for sighted keyboard-only users. There are a few ways we could do that.
Hide the refresh button with the. REJECTED in #2, it was being overridden by author styles..hiddenclass instead of.visually-hidden- Hide the refresh button with the
.hiddenclass instead of.visually-hidden, and provide a more specific override (like toolbar and contextual modules do, see comment #8). - Use a custom class for this button, and use
display:noneon that. WORKS see comment #2. - Use the HTML5
hidden attributeinstead of the.visually-hiddenclass. See comment #8.
Important: will the button still accept a programatically-triggered mousedown event?
- YES, still works in Firefox.
- TODO: confirm this still works in other browsers.
Remaining tasks
- Patch to hide the button
- Make sure the need to hide it from all users is documented in comments.
- Cross-browser testing - test the tabbing order in all our supported browsers, confirm the button isn't tabbable.
- Cross-browser manual testing - Confirm the
trigger('mousedown')inDrupal.fieldUIOverview.AJAXRefreshRows()still works, in all our supported browsers.
User interface changes
Accessibility improvements - remove the confusing button from the keyboard-only and screen reader experience.
No visual design changes.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|
Issue fork drupal-2990588
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 2990588-visually-hidden-refresh-button
changes, plain diff MR !8174
Comments
Comment #2
andrewmacpherson commentedThis patch replaces the
.visually-hiddenclass with a custom class, which gets CSSdisplay:none.First I tried using Drupal core's existing
.hiddenclass, but it wasn't specific enough and was overridden by button styles. Feel free to suggest a better class or selector.The patch here adds the new style rule to the Stable theme. I hope that's OK - we've allowed accessibility bug fixes in Stable theme before now.
Will this need cross-browser testing? So far I've only tested this in Firefox 61 (Linux). It seems a
mousedownevent can still be programatically triggered on a button withdisplay:none, which is good. I used a few console.log lines infield_ui.jsandajax.jsto check this.Comment #3
andrewmacpherson commentedThe previous patch only worked on "manage form display", not "manage display", so I've updated the selectors and button class.
Manually tested in Firefox 61 (Linux) and Chrome 68 (Linux), with Seven and Stark themes.
Comment #4
andrewmacpherson commentedWill this need cross-browser testing?
Comment #5
andrewmacpherson commentedComment #6
shaalI tested on Ubuntu 18.10, with the following setup
After applying the patch, testing
/admin/structure/types/manage/article/form-displayand/admin/structure/types/manage/article/display.Tabbing through the elements on the page, it does skip the visually-hidden button just before the save button.
Comment #7
oriol_e9gWhy not add !important in hidden helper class
.hidden { display: none !important; }like bootstrap? We are adding other importants in similar classes, and it's fine to force hidden if you use hidden class.Comment #8
oriol_e9gPlease, feel free to commit patch #3 if considerer that it's better create a new class instead to add an !important in a current class, #3 still RTBC.
Comment #9
oriol_e9gComment #10
oriol_e9gComment #11
andrewmacpherson commentedRe. #6 - Thanks @shaal, I see you tested the tabbing order.
Did you test whether the FIeld UI Javascript behaviours still work?
The part we need to know about is whether the hidden refresh button still works. Does triggering a
mousedownprogramatically still work for a button withdispay: none? I think that warrants cross-browser testing too.See my comment in #2 about this. The mousedown is triggered in
Drupal.fieldUIOverview.AJAXRefreshRows(). It's a while since I had my head in this issue, and I find our AJAX system hard to grok. I'm not really clear what the refresh button if for. I can't recall where I put theconsole.loglines I mentioned. Manual testing involves changing formatter, formatter settings, etc.Re. #7-10
That's certainly a good suggestion to consider, but I'd be very cautious about changing the implementation of
.hiddenin a minor release. It would potentially break things far beyond the refresh button in this issue, including existing sites. I'd defer to the framework managers about that. Can we file a follow-up issue about it making.hiddenmore robust generally, and keep this issue scoped to this button.Also, my own ideas further to. #2
I also noticed that other modules (contextual, toolbar, off-canvas) have run into the problem of
.hiddenbeing overridden. They all solve it like this, with a more specific selector for the.hiddenclass like this:So perhaps we should follow that pattern instead of the custom class I used in #2. It has the advantage of being easy to understand in the HTML without looking up the styles.
I don't recall if I tried using the HTML5
hiddenattribute. That would allow us to avoid a custom class to the stylesheets. However the hidden attribute is typically implemented asdisplay:nonein user-agent styles, so they might also get overridden by author style. Adding that as something to try.Updating the issue summary. Confirming the JS behaviour still works is the most important thing for review.
Comment #12
tim.plunkettFixing tag
Comment #22
mgiffordTagging
Comment #25
utkarsh_33 commentedI have added a custom class to take of all the things described in the remaining tasks.I was able to hit the breakpoint for
atleast in Chrome.
The failing test seems to be random failures as they are failing on 11.x as well(atleast on my local).Marking it as needs review just to get an initial round of review.
Comment #26
smustgrave commentedHiding patches for clarity.
On a standard profile install of 11.x
Can confirm on /admin/structure/types/manage/article/form-display that tabbing through the page that focus is lost between the last gear icon and the "Save" button.
Applied the MR and focus no longer appears to be lost.
Solution of using a custom class also appears to be least disruptive in my opinion especially since it can be added this way. Wonder if there is other places this is also fixing.
Looks great to me!
Comment #27
smustgrave commentedWrong tag
Comment #28
nod_Reading the IS the problem is that keyboard focus is possible.
tabindex="-1"would fix that, can someone confirm that it works? Adding a new class and a bunch of display:none in the CSS is not the way to go.Comment #29
utkarsh_33 commented#28 seems to be a better approach, so I have reverted the class changes and added tabIndex to the button thus making it non tabbable.Also the mousedown trigger event is working so marking it as needs review again.Thanks!
Comment #30
nod_need a small comment
Comment #32
mithun sAdded a rebase of the latest changes from the branch.
The MR looks mergable now. Thank you!
Comment #33
smustgrave commentedFeedback appears to be addressed.
@Mithun S thanks for the rebase but only needed if the MR is unmergable just an FYI.
Comment #39
nod_Committed and pushed b97be27a89 to 11.x and 68a22a5cc0 to 11.0.x and 6e1e0c29d0 to 10.4.x and d0592e79ef to 10.3.x. Thanks!