Best way to control keyboard navigability within an element (scope to parent)
I'm trying to find the best way to guide users through some of these modals we have in the UI (example pictured)
I've tried several things.
• Tabindex was my first thought but its a nightmare. All default elements throughout the entire application are tabindex 0 or -1 if we don't want them to be focusable, but Giving this CTA button atab index of 1 and the cancel button a tab index of 2 is no good. The tabindex 0s in the page BEHIND the modal take precedence over anything with a positive integer attribute value so I would have to explicitly give EVERYTHING in the modal form a tab index of 1
• Flex order https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Ordering_flex_items#the_order_property but then the HTML looks funny against the UI without the developer leaving the markup and inspecting the CSS
• Flex direction: Set the row of buttons as reversed and leave a code comment, this is the best so far but just wanted to check
What I was really hoping was that there was something like the stacking context css rule
isolation: isolate;
I could add to the parent element to give its children a "scoped" tab index. But it would appear none such thing existsMDN Web Docs
Ordering flex items - CSS: Cascading Style Sheets | MDN
Layout methods such as flexbox and grid enable controlling the order of content. In this article, we will take a look at ways in which you can change the visual order of your content when using flexbox. We will also consider how reordering items impacts accessibility.
4 Replies
The 1 thing stopping me from just using flex row reverse and calling it a day is we also have UI like this
I know that row of buttons in the bottom of the modal with multiple pages/tabs should just flow focus left to right or right to left, but it would kind of be nice if the tab priority was next, previous, THEN cancel
This modal shown uses tab index and then a hack so when the last element in the form loses focus, and event fires to manually give focus on the "next" button but I recently discovered when using the app that this totally screws with uses who want to "shift + tab" backwards navigate up to the form as going backwards from the first element with a positive integer tab index starts at the last element with tabindex of 0 somewhere else on the page behind the modal.
I think putting th cancel button right beside next is not a good idea
Maybe you should put it under the Jobsite checklist and use row reverse abd flip html between checklist and form
I feel like it's a bit dangerous for misclicking
I would have thought that
order
would be the best method for what you want to do. I can't see why the "funny" order in the HTML should be a concern.I don't do the UI design. By the time it gets to me, its been reviewed and gone through 10-20 revision and approved by the product owner and project manager so I can raise concerns if soemthing seems funny to me but I don't have the liberty to arrange the layout without a lot of red tape.
Also, these forms have change detection, and when a user has provided any information to any input accross the 4 pages of this modal, the cancel button gets protected by a confirmation dialog box:
Header: Close {Modal name here}?
Body text: You have unsaved changes that will be lost.
Buttons: [ KEEP EDITING ] [ CLOSE ]
Yeah, this is probably the best solution. I'll just configure the order in the CSS and I suppose I'll try to get the css closer to the markup.
Most of our styles are written in feature-scoped stylesheets that are compiled by webpack into a distribution minified master stylesheet in a separate repository than the application code and markup. We recently figured out we had a configuration error in our project that was preventing using our framework's scoped styles for each component and that's been fixed so I just need to get used to it. I think having the styles close to the code will give the other devs on the team a better understanding of things like HTML flow differing from the UI because of the css.