I would like to be able to provide a tabbed interface on a website, without having to use JavaScript. Clicking on a tab should display the corresponding tab panel, and the HTML markup alone should be fully accessible (keyboard, screen reader).
Hmm not sure how something like this would work without Javascript without making many many assumptions about what should happen. There are a many things that need to be either explicitly declared in your markup or implied.
When does a tab get transitioned to? After a âclickâ, maybe when enter key is pressed?
If transition is triggered by a key press, which variation? âkeyDownâ, âkeyUpâ?
How should the content load once transitioning to a tab? (Lazily vs eager)
Should the tab content already be in the DOM waiting to be shown? Or injected when its requested?
Should the tab content be cached upon first view? If so, when do we query for up-to-date content?
Should it have a loading spinner?
If there is a loading spinner, when should it show/hide? Right before content is shown?
How would the loading spinner get displayed? Fade in? Fade out? Css transition? Css Animations?
1 and 2. Keyboard interaction with tab controls is standardized in ARIA, so that is taken care of.
3, 4 and 5. The tab control is merely responsible for displaying the correct tab panel. Whether or not tab panels are prepopulated or lazyloaded is up to the web app.
6, 7 and 8. No loading indicator is needed since the tab panel is displayed immediately (itâs the same mechanism as with the <details>/<summary> elements).
I hope this makes it clear that my proposal is only for a basic tabbed UI functionality.
Also, ARIA standardising keyboard control through adding javascript isnât necessarily a good answer. There are cases where different platforms do, and probably should do, something other than what the ARIA models propose, generally based on Windows if there are differences.
I quite like the panel and panelset idea. Itâs got a good balance of high level semantics without overly restricting developers. The mediaquery control of preferred-display is particularly nice.
Iâm not sure what âtrump the original claimâ means. Does it mean that expanding another panel automatically collapses the previously expanded panel? This would be needed for built-in interaction functionality in a a tabbed interface, which is what I want.
Also, having to set the expandable attribute on each panel isnât optimal (it would be code repetition, since a tab panel is expandable by design); it would be nice if the attribute could be set on the panel set element.
In making it, I didnât feel as though I really needed additional elements, however that meant relying heavily on ARIA attributes. What I felt was lacking were certain CSS selectors.
Itâd be great if there were a way to use attribute references in selectors in some way so that a checkbox could select its own label(s), and a label could select its checkbox. Given how many ARIA attributes are IDs or lists of IDs, this would significantly improve ARIA in general.
All that said, there are certainly some issues. Without JS thereâs no way to manage state such as the aria-expanded attribute. Having some dedicated elements that have explicit behavior could simplify implementations, and make it easier for developers to build tabs correctly, rather than a bunch of <div>s with onclick.
Thanks for summarizing it in a terse list . Until, this gets standardized in HTML, the best solution for web developers is to use an âARIA tabsâ library, I think.
Iâm sure there are a bajillion reasons why this sort of selector canât and wonât exist, and I have no idea what sort of specificity the selector would have, but I can guarantee that if I had access to something like it, Iâd use it all the time.
Iâm not sure what âtrump the original claimâ means. Does it mean that expanding another panel automatically collapses the previously expanded panel?
Yes, basically it is explaining what a single with options would do⌠If you say
JFTR, there used to be a solution for that in Selectors 4 drafts (subject indicator $ and reference combinator /âŚ/), but the latter part is gone and the former has been replaced by :has().