A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

Standard tab control

simevidas
2016-07-26

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).

An example of a tab UI is Gmail:

mkay581
2016-07-27

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.

  1. When does a tab get transitioned to? After a ‘click’, maybe when enter key is pressed?
  2. If transition is triggered by a key press, which variation? ‘keyDown’, ‘keyUp’?
  3. How should the content load once transitioning to a tab? (Lazily vs eager)
  4. Should the tab content already be in the DOM waiting to be shown? Or injected when its requested?
  5. Should the tab content be cached upon first view? If so, when do we query for up-to-date content?
  6. Should it have a loading spinner?
  7. If there is a loading spinner, when should it show/hide? Right before content is shown?
  8. How would the loading spinner get displayed? Fade in? Fade out? Css transition? Css Animations?

I’ve only scratched the surface here…

simevidas
2016-07-27

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.

DanielHerr
2016-07-27

Should the <details/summary> style be reused for this? If so, what should the element names be?

chaals
2016-07-27

please look at Panels and panelsets

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.

chaoaretasty
2016-07-27

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.

simevidas
2016-07-27

@chaals @chaoaretasty I like the panel/panel sets proposal.

The first panel element within a panelset element should be expanded by default. Any subsequent claims of expansion trump the original claim.

Source: https://specs.webplatform.org/common-panel/bkardell/gh-pages/#the-panelset-element

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.

zzzzbov
2016-07-30

Reading the “requirements” of this particular discussion

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
  • the HTML markup alone should be fully accessible

I mocked up a quick proof-of-concept with HTML, CSS, and no JS.

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.

simevidas
2016-07-31

Thanks for summarizing it in a terse list :blush:. Until, this gets standardized in HTML, the best solution for web developers is to use an “ARIA tabs” library, I think.

Crissov
2016-07-31

So you’d basically like to be able to simplify rules like these

#tab-1:checked ~ [role="tablist"] [for="tab-1"], 
#tab-2:checked ~ [role="tablist"] [for="tab-2"], 
#tab-3:checked ~ [role="tablist"] [for="tab-3"] {
  background-color: #FFF;
}
#tab-1:checked ~ #tab-panel-1, 
#tab-2:checked ~ #tab-panel-2, 
#tab-3:checked ~ #tab-panel-3 {
  display: block;
}

to something like this?

.tab:checked >>> label {
  background-color: #FFF;
}
.tab:checked >>> .panel {
  display: block;
}
zzzzbov
2016-08-01

Yes, although the syntax needs to be worked out.

Something like

label:attr(for, input:checked, id)

could work to select the labels where the [for] attributes matche the input:checked elements’ id attributes

In the example, this would replace

#tab-1:checked ~ [role="tablist"] [for="tab-1"] {
  background-color: #FFF;
}
#tab-1:checked ~ #tab-panel-1 {
  display: block;
}
...

with

.tabs__tab:attr(for, .tabs__radio:checked, id) {
  background-color: #FFF;
}
.tabs__panel:attr(id, .tabs__tab:attr(for, .tabs__radio:checked, id), aria-controls) {
  display: block;
}

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.

briankardell
2016-08-01

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

If the markup is at odds, the last one wins.

Crissov
2016-08-01

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().

$label /for/ input:checked {}
label:has(/for/ input:checked) {}