whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
7.87k stars 2.58k forks source link

[Proposal] New tags <tabsection>, <tablist>, <tab>, <tabpanel> #1809

Open Mevrael opened 7 years ago

Mevrael commented 7 years ago

Today tab panels and menus to switch panels are used almost in every app, however, it is possible only with the help of JavaScript.

We already have ARIA role="tablist", role="tab" and role="tabpanel".

I am proposing adding new native HTML widget so browser could handle this job itself:

<tabsection>
  <tablist>
    <tab selected>Tab 1</tab>
    <tab>Tab 2</tab>
  </tablist>
  <tabpanel>
    Panel 1
  </tabpanel>
  <tabpanel>
    Panel 2
  </tabpanel>
<tabsection>

<tabsection> is an optional wrapper. If this wrapper is used, then IDs in tabpanels can be ignored, otherwise each tab should have a reference to tabpanel which is triggered by pressing on corresponding tab:

<tablist>
   <tab for="panel1">Tab 1</tab>
   <tab for="panel2">Tab 2</tab>
</tablist>

...

<tabpanel id="panel2">
  Panel 2
</tabpanel>

...

<tabpanel id="panel1">
  Panel 1
</tabpanel>
stevefaulkner commented 7 years ago

@Mevrael you may want to take a look at the panel and panelsets proposal https://discourse.wicg.io/t/panels-and-panelsets/1184

domenic commented 7 years ago

Hi @Mevrael, welcome to the HTML Standard. Could you help us understand the use case better? You've jumped straight to a solution, but it's important to discuss the problem space more first. See https://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F

In particular, I'm interested in which of your use cases and requirements are "must have", and which are "nice to have". It seems (I might be wrong) that one of your requirements is not using aria-* attributes. I'm curious to understand whether that is a must have, and if so, why.

Mevrael commented 7 years ago

Hi @domenic, thank you for responce and the link.

I am talking about adding a new component with it's own API also, like we have a <select> , for example or a new <dialog>.

The purpose of that is to standardize the making of tabs and switching the sections accross the Web, and provide JS/DOM API such as tabList.selectedTab and tabSection.swicthTab(). Right now everyone is implementing tabs in his own way, some people are using checkboxes for that, some CSS :taget etc. In any case people have to write custom JS for such simple widget.

The use case is very wide. Making simple menus and single page applications, tabbed sections. Divide large forms into sections is also recommended from UX point of view. Many online documentations and WHATWG HTML spec also could be divided into smaller sections. With the help of CSS <tablist> can be rendered as a small left column of tabs. Also take a look on GitHub issue form itself, there are tabs Write and Preview or I'm sure you've seen Sign in / Sign up modal windows with tabs like (Sign in / Sign up)

Right now we have markup like <div class="tab" role="tab"> (however in reality we almost don't have accessible tabs) and JS API of each 3rd party library is very different. HTML5 already added new semantic tags like <header>. Web is changing and in future we will need more dynamic web widgets standardized, probably, with animation support. <dialog> is first, and I'm sure, not the last.

By default all tabpanels are hidden and the only one can be shown at the time.

There is no need to specify ARIA attributes since it should be part of component itself like <button> already has role="button" by default, so the default role for <tab> will be tab, but, of course, it can be changed with the role attribute and in that case <tab> won't be a tab anymore from semantics and accessibility point of view.

After thinking a bit, I changed my first implementation and added also a <tabpanellist>. If <tabsection> is not used then only <tablist for="tabpanellist_id"> should be connected with <tabpanellist id="tabpanellist_id">. It's better then specifying target of each tab separately.

New DOM events like tabswitch.

The CSS animations and transitions could be now also easily added without JS:

tab:selected {
  background: #DDD;
}

tab {
  background: #FFF;
  transition: 0.2s ease background;
}

tabpanel {
  opacity: 0
  transition: 0.2s ease opacity;

tabpanel:shown {
  oapcity: 1;
}

May be we could even expand this widget to let it be also an accordion. Here is a good 1st answer about many options http://ux.stackexchange.com/questions/76634/tabbed-content-vs-scrollable-list

bkardell commented 7 years ago

@Mevrael as @stevefaulkner said above, we'd welcome participation in the panel/panelsets thing which aims to do this and some more and already has a lot of participation/thought into it.

Mevrael commented 7 years ago

@bkardell Yeah, thanks, I will join that topic when will have time to read all the posts.

Are there any recommendations on when GitHub should be used and when discourse.wicg.io?

Also does WHATWG or any group has Slack room? It is much easier to discuss such topics real-time and not in the oldfashion forum-style way.

There is also a new topic about tabs https://discourse.wicg.io/t/standard-tab-control/1621/10 Are they going to be merged/closed? If so, how user can inform moderator/admin about that?

zcorpan commented 7 years ago

This appears to be the same idea as the switch element which was in the spec 10 years ago but was removed sometime in 2006 or 2007 (due to lack of implementor interest I believe):

https://whatwg.org/specs/web-apps/2006-01-01/#switch

We still need implementor interest. :-)

As for where to discuss, it's OK to discuss this feature in this issue if you like. We don't have a Slack room as far as I know, but we do use IRC.

zcorpan commented 7 years ago

switch and tabbox were removed in 438d3386acc69747245f9c0d9015d3867b82d9a1

chharvey commented 6 years ago

I’m on board with an HTML tabbed panel interface. It’s used often enough that there should be a standard way to define its semantics and user interaction. Currently, authors must carry the burden of implementing the interface themselves, which requires having the knowledge and experience of:

The mere number of ways to implement these almost certainly leads to inconsistency and lack of user agent accommodation. (For what it’s worth, I prefer the element names <tablist>, <tab>, and <tabpanel> after the ARIA roles.)

I wrote a little demo tab interface on CodePen, using Custom Elements with full ARIA and keyboard support, JavaScript-less users get a fallback: https://codepen.io/chharvey/pen/bYyMqN

And accommodated it with what a mockup specification would look like: http://dev-chharvey.github.io/blog/html/tablist.html

Any feedback is welcome, if you feel so inclined!

Yay295 commented 6 years ago

I think CSS styling would be the most complicated part of this. There are a lot of different ways tabbed interfaces have been implemented, so it would take a lot of options to be able to support even the most common.

The only benefit I see to this is being able to have tabs without JavaScript, but I question the usefulness of that with the limited number of people who would be unable to use a regular JavaScript version.

@chharvey "It is best viewed in the Google Chrome browser." It only works in Chrome.

chharvey commented 6 years ago

Safari v11.0.2 for macOS Sierra (10.12.6) seems to also support Custom Elements. In either case, here’s a non-Custom-Elements version, which uses <details> and <summary>. It works in Chrome, Safari, and Firefox Quantum; I haven't tested Edge.

Tabbed interfaces are very popular in modern web apps, especially those that can’t use paginated navigation due to loading issues (e.g. a slideshow webapp). A JavaScript-less standard would help with that. The argument for this is almost identical to the argument for the <details> element.

PS: I’m working on introducing a "close" button to the tabs, to resemble a browser window in which the user can close tabs and remove them from the interface, so stay posted.

muan commented 5 years ago

Also take a look on GitHub issue form itself, there are tabs Write and Preview

As @Mevrael mentioned there are a few tabs on github.com, so we ended up building https://github.com/github/tab-container-element for our tab-like interface needs. However, we are very cautious currently in converting legacy tabs (Write/Preview tabs) to <tab-container>, because it could break user's current expectation of the keyboard interaction. The ideal pattern seems to be still controversial. Specifically:

  1. Should tab buttons (active and inactive ones) be
    • keyboard tabbable
    • navigated with left/right arrows
    • navigated with up/down arrows
  2. Should the active tab panel be
    • focusable
    • navigated to with down/right arrow depending on the tab interface orientation
  3. How should developers/would users distinguish tab interfaces that are really navigation links styled as tabs from ones that are tabbable panels on a page? For example:

    This affects people's expectation on the keyboard interaction tabs should have. The primary argument I've seen is that tabs are supposed to have a radio group-like keyboard interaction pattern, but that falls apart in the navigation like interfaces.

Some relevant discussions that I've seen:

I don't think there's yet a consensus on the aforementioned issues though, since the best practice hasn't been updated to address some people's concerns. It might well be that they have been considered and dismissed, but it hasn't stopped the confusions. From my perspective it seems a big part of this problem is the 3rd bullet point above– if there's a better definition on their differences, it would probably be easier to tell what should be expected.

And in my opinion it is just that— navigation links aren't tabs, though they look like tabs. And that is just a design issue, like all the buttons that look like links across the web. 😔

Dan503 commented 5 years ago

These are my thoughts on the topic:

Why?

Tabs are a very popular interface component found in both applications and web pages.

Making Tabs accessible can be a difficult task for developers resulting in many implementations being inaccessible.

How tabs are supposed to function via keyboard can also vary from site to site resulting in a confusing and inconsistent user experience for keyboard users in general.

The W3C has outlined what they feel makes for ideal tabs here: (manual switching) https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-2/tabs.html

And here: (automatic switching) https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html

There have been usability issues identified with the W3C recommendations though: https://simplyaccessible.com/article/danger-aria-tabs/#acc-heading-2

The main issue being that people often do expect the tabs to appear in the tab sequence. If tabs became standardized in HTML with arrow based functionality though, this issue would quickly go away as people got used to seeing them.

If tabs became native elements, it would:

Proposed markup

(basically the same as what others have proposed)

<tabcontainer aria-label="Entertainment">

  <tablist>
    <tab selected>Nils Frahm</tab>
    <tab>Agnes Obel</tab>
    <tab>Joke</tab>
  </tablist>

  <tabpanel>
    <p>Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.</p>
  </tabpanel>

  <tabpanel>
    <p>Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.</p>
  </tabpanel>

  <tabpanel>
    <p>Fear of complicated buildings:</p>
    <p>A complex complex complex.</p>
  </tabpanel>

</tabcontainer>

Equivalent to writing this:

<div class="tabs">

  <div role="tablist" aria-label="Entertainment">
    <a href="#nils" role="tab" aria-selected="true" aria-controls="nils" id="nils-tab">
      Nils Frahm
    </a>
    <a href="#agnes" role="tab" aria-selected="false" aria-controls="agnes" id="agnes-tab" tabindex="-1">
      Agnes Obel
    </a>
    <a href="#joke" role="tab" aria-selected="false" aria-controls="joke" id="joke-tab" tabindex="-1">
      Joke
    </a>
  </div>

  <div tabindex="-1" role="tabpanel" id="nils" aria-labelledby="nils-tab">
    <p>Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.</p>
  </div>

  <div tabindex="-1" role="tabpanel" id="agnes" aria-labelledby="agnes-tab" hidden>
    <p>Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.</p>
  </div>

  <div tabindex="-1" role="tabpanel" id="joke" aria-labelledby="joke-tab" hidden>
    <p>Fear of complicated buildings:</p>
    <p>A complex complex complex.</p>
  </div>

</div>

Just by looking at the difference between the two examples you can easily see how much of a need there is for this.

Proposed functionality

A :selected CSS psudo selector will need to be introduced to allow authors to style the active tab element.

Possibility one:

I was thinking of using the arrow keys with automatic tab switching as the standard default functionality: https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html

Two small exceptions:

If a manual="true" attribute is added to the <tabcontainer> element, it has functionality more reminiscent of the manual example: https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-2/tabs.html (same 2 exceptions apply)

If a selected attribute is not used on one of the <tab> elements, the first <tab> should be selected by default.

Possibility two

However after reading the comment by @muan it might be better to use this sort of functionality by default:

https://codepen.io/daniel-tonon/pen/vqWmJy

(ie. tabs are controlled using the [tab] and [enter] keys)

That sort of functionality would mean there is no confusion if people design links to look like tabs in a design.

I'm not sure if we should dictate the functionality of a HTML element based on peoples bad design decisions though. 😕

How does the browser know what panel belongs to what tab?

If there is only one <tabpanel> in the <tabcontainer> it is considered always active and is associated with whatever the active is at the time. This is so that people who want to dynamically load in the tab content can do so easily.

If there are an equal number of <tabpanel> to <tab> elements inside the <tabcontainer>, the 1st <tab> will control the 1st <tabpanel>, the 2nd <tab> will control the 2nd <tabpanel>, and so on until all tabs and tab panels are accounted for.

If there is more than one <tabpanel> element but the number of <tabpanel> to <tab> elements is not equal to one another, it is considered invalid HTML.

Yay295 commented 5 years ago

If there is more than one <tabpanel> element but the number of <tabpanel> to <tab> elements is not equal to one another, it is considered invalid HTML.

We can completely avoid that issue by removing the <tablist>.

<tabcontainer aria-label="Entertainment">

  <tabpanel selected name="Nils Frahm">
    <p>Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.</p>
  </tabpanel>

  <tabpanel name="Agnes Obel">
    <p>Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.</p>
  </tabpanel>

  <tabpanel name="Joke">
    <p>Fear of complicated buildings:</p>
    <p>A complex complex complex.</p>
  </tabpanel>

</tabcontainer>
Dan503 commented 5 years ago

...I would consider that invalid as well then.

scottaohara commented 4 years ago

Removing the author requirement of having to construct a tablist and keeping it in alignment with the different tabpanels doesn't seem like such a bad idea to me.

e.g. if a tablist can be generated from the different names of the tabpanels, then the main downside I see to that is it'd create a hurdle for anyone who wanted to inject say an SVG icon to precede any tab text labels.

Dan503 commented 4 years ago

@prlbr raises an interesting option in this comment: https://github.com/w3c/html/issues/1704#issuecomment-513224155

He proposes syntax like this:

<tabcontainer aria-label="Entertainment">

  <tabpanel>
    <tab selected>Nils Frahm</tab>
    <p>Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.</p>
  </tabpanel>

  <tabpanel>
    <tab>Agnes Obel</tab>
    <p>Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.</p>
  </tabpanel>

  <tabpanel>
    <tab>Joke</tab>
    <p>Fear of complicated buildings:</p>
    <p>A complex complex complex.</p>
  </tabpanel>

</tabcontainer>

This helps keep the tab relative to the tabpanel that it is associated with in the HTML.

The downside to this is that it would need to become a replaced element and rely on the shadow DOM instead of direct styling. There might also be performance issues with it. It might also be difficult for browsers to implement.

Styling could still be handled using psudo-element selectors though. For example, styles might look like this:

tabcontainer {
  /* outer container styles */
}

tabcontainer::list {
  /* wrapper around the tab buttons styles */
}

tabcontainer::tab {
  /* tab button styles */
}

tabcontainer::panel {
  /* tab panel styles */
}