type: widget
release: 1.5
priority: -
status: complete
documentation: http://docs.jquery.com/UI/Tabs
demo: http://jqueryui.com/demos/tabs
1 - Description:
A tab strip is used to chunk sections of content into multiple panes that can be shown one at a time, much like the sections in a notebook. Depending on the size of the window and length of tab labels, you can create a tab view that contains between two and six to eight tabs. This rule of thumb is followed because tab strips should never wrap to multiple rows or insert horizontal scrollers for the tabs because of the poor visual connection between the tab and the pane below (yes, these have been seen in the past, but is not a good thing). If there are too many items to fit in a tab strip, consider re-grouping the tab content into fewer tabs or moving to a different navigation widget like a vertical left navigation bar or tree which can accomodate a larger number of items.
There is a current tab widget in the UI library that needs to be extended to allow for vertical tabs (left or right orientation):
http://docs.jquery.com/UI/Tabs
http://jqueryui.com/demos/tabs
Detailed tab behavior descriptions can be found for Apple OS X and Microsoft Windows.
2 - Visual Design:

3 - Functional Specifications/Requirements:
Options/Methods/Callbacks
- options:
- selected (integer, default: 0)
- Zero-based index of the tab to be selected on initialization. To set all tabs to unselected set this option to -1 (null is deprecated).
- deselectable (boolean, default: false)
- When set to true, clicking a selected tab will unselect it.
- event (string, default: "click")
- Name of the event that is used for selecting a tab. To select on hover, use "mouseover".
- disabled (array, default: [])
- Array of zero-based tab indices that will be disabled on initialization. Disabled tabs cannot be selected by the selection event.
- cookie (object, default: null (no cookie used))
- Save the currently selected tab in a cookie. This value is then being used to determine the initially selected tab if the selected option is not defined. Requires the jQuery cookie plugin.
- The options in this object are passed through to the jQuery.cookie method.
- Additional option: name (string, default: UUID generated from jQuery.data method) (the cookie's name)
- spinner (string, default: "Loading…")
- While remote content is loading, this HTML content will be displayed in the tab title area. To disable the feature, set to an empty string.
- cache (boolean, default: false)
- By default, tabs that load remote content will re-request the content each time the tab is re-selected. Set this option to true to have the remote content requested only the first time and cached for subsequent selections.
- ajaxOptions (object, default: {})
- The options in this object are passed through to the jQuery.ajax method on remote content loads.
- idPrefix (string, default: "ui-tabs-")
- For generation of ids for newly added tab panels.
- fx (object or array of 2 objects, default: (no effects used))
- The options in this object/these objects are passed through to the jQuery.animate method.
- If objects are given in array, the first object defines the hide, the second one the show animation being used.
- tabTemplate (string, default: "<li><a href="#{href}"><span>#{label}</span></a></li>")
- panelTemplate (string, default: "<div></div>")
- Template to create a new tab content panel from.
- methods:
- select
- load
- add
- remove
- enable
- disable
- url
- destroy
- length
- rotate
- callbacks:
- select (event: tabsselect (custom))
- load (event: tabsload (custom))
- show (event: tabsshow (custom))
- add (event: tabsadd (custom))
- remove (event: tabsremove (custom))
- enable (event: tabsenable (custom))
- disable (event: tabsdisable (custom))
- 'ui' object:
Specificiations
- Indices are generally zero-based.
- select callback: triggers when a tab is selected by event as defined in event option or programmatically via select method. If this function returns false, the requested tab won't become selected.
- load callback: triggers when an ajax tab successfully has loaded content, either explicitly via load method or implicitly by selecting a tab.
- show callback: triggers when the selected tab is shown. In case of animation being defined for showing this means after the animation is complete.
- The aforementioned callbacks are thus triggered in the following order: 1. select, 2. load (ajax tab only), 3. show.
- add callback: triggers when a new tab has been added via add method.
- remove callback: triggers when a tab has been removed via remove method.
- enable callback: triggers when a tab has been enabled via enable method.
- disable callback: triggers when a tab has been disabled via disable method.
- There are 4 possibilities to set the initially selected tab:
- selected option (highest priority)
- url fragment identifier matching a tab href's fragment identifier: href="#fragment-identifier",
- from cookie,
- the according class attribute is already specified in HTML source: <li class="ui-tabs-selected"> (lowest priority)
A possibly arising conflict is resolved by giving each alternative a different priority, as denoted.
-
It is possible to initialize an empty tab set and add tabs later on.
-
A selected tab cannot be deselected by selecting it a second time unless option deselectable is set to true.
-
A selected tab cannot be disabled.
-
If the selected tab is being removed the one to the right is selected as long as it is not the last one at the same time - in this case the one to the left is selected (mimicing behavior in Firefox).
-
The type of tab (in-page vs. ajax) is determined automatically from the href attribute of the contained anchor elements - an href being solely a fragment-identfier href="#fragment-identifier" results in an in-page tab, an href pointing to an existing resource href="/path/to/resource.html" results in an ajax tab. External URIs are not supported due to security restrictions with ajax.
Css Classes
The following markup is used in tab implementation with added classes in bold (note this is the rendered source):
Sample Markup
<div style="display: block;" id="tabs" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
<li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active">a href="#tabs-1">First</a></li>
<li class="ui-state-default ui-corner-top"><a href="#tabs-2">Second</a></li>
<li class="ui-state-default ui-corner-top"><a href="#tabs-3">Third</a></li>
</ul>
<div id="tabs-1" class="ui-tabs-panel ui-widget-content ui-corner-bottom">Tabs 1 Panel Content</div>
<div id="tabs-2" class="ui-tabs-hide ui-tabs-panel ui-widget-content ui-corner-bottom">Tabs 2 Panel Content</div>
<div id="tabs-3" class="ui-tabs-hide ui-tabs-panel ui-widget-content ui-corner-bottom">Tabs 3 Panel Content</div>
</div>
List of Classes - and Explaination:
In the Container Div:
ui-tabs -
ui-widget -
ui-widget-content -
ui-corner-all -
In the Unordered List that makes up your Tabs:
ui-tabs-nav -
ui-helper-reset -
ui-helper-clearfix-
ui-widget-header-
ui-corner-all
In the List tags themselves (these are your actual tabs):
ui-state-default -
ui-corner-top -
ui-tabs-selected -
ui-state-active -
In Panels that contain your content:
ui-tabs-hide -
ui-tabs-panel -
ui-widget-content -
ui-corner-bottom -
Changes from 1.5, 1.6rc5 in refactor
- setting all tabs to unselected via value -1 instead of null (deprecated)
4 - Markup & Style:
4.1 Initial markup examples
(Pre-enhanced HTML markup structure that will be transformed into the final widget. There may be multiple possible HTML markup options per widget: for example, for a slider, radiobuttons, inputs or selects could all be used. )
4.2 Recommended transformed HTML markup demo with html and css (live view of git):
View Demo Page: http://view.jqueryui.com/master/tests/static/tabs/tabs.html
(The HTML markup structure and classes that will be used by the scripts in the enhanced version)
4.3 Markup & style browser QA status
As of 12/12/08, static markup for this widget renders correctly in the following browsers. (Correct rendering = true to design, with only small differences across browsers owing to differences in support of rounded corners, and native OS form element and font rendering.)
Please update this list as more browsers / platforms are tested.
|
|
XP
|
Vista
|
Mac 10.5
|
|
IE 6
|
|
|
|
|
IE 7
|
|
|
|
|
IE 8
|
|
|
|
|
Firefox 2.0.0.18
|
|
|
|
|
Firefox 3.0.4
|
|
|
|
|
Safari 3.2
|
|
|
|
|
Opera 9.1
|
|
|
|
|
Opera 9.62
|
|
|
|
|
Chrome 3
|
|
|
|
4.4 Accessibility recommendations
Required ARIA Markup:
- role="tablist" for the outer container element
- role="tab" for each tab element
- role="tabpanel" on each tab panel element
- aria-selected="true/false" for each tab, depending on whether the tab is currently the active one in the tablist
- aria-expanded="true/false" for each tab panel, depending on whether the corresponding tab is currently expanded. This is specifically important for tabs that allow each tab to be collapsed.
- aria-controls="<ID>" on each tab, references the ID of the tab's corresponding panel element
- aria-labelledby="<ID>" on each tab panel, references the ID of the panel's corresponding tab element (in other words, the tab provides the accessible name for the panel)
- aria-live="polite" on tab panels that load remote content
- aria-busy="true/false" on tab panels with remote contents. The value will be "true" while the panel contents are loading, indicating to assistive technology that the content is not available yet.
Keyboard Accessibility:
To comply with the DHTML Styleguide, the following keystrokes need to be supported:
- For tab elements:
- Left / Up arrow: Select and focus previous tab (if first tab has been reached, wrap to the last)
- Right / Down Arrow: Select and focus next tab (if last tab has been reached, wrap to the first)
- Ctrl + arrow keys: Change focus to the next / previous tab without selecting it. This is useful to allow (screen reader) users to explore the available tabs without triggering remote content (as this could have a high performance in bandwidth and delay). The Space /Enter key can then be used on the focused, unselected tab to select and expand it.
- Home: Select and focus first tab
- End: Select and focus last tab
- Enter / Space: Toggle the tab's expanded state (for tabs that allow each tab to be collapsed)
- alt + del: Delete the currently selected tab (for tabs that allow this)
- Inside Tab Panel:
- Alt + Del: Delete the currently selected tab (for tabs that allow this)
- Ctrl + PageUp: Select, expand and focus the tab associated with the previous tab panel (or wrap to the last)
- Ctrl + PageDown: Select, expand and focus the tab associated with the next tab panel (or wrap to the first)
- Ctrl + Up Arrow: Focus tab coresponding to the currently opened panel
A choice needs to be made between two types of keyboard interaction:
- Each tab is part of the web page's tab order, the Enter key is used to activate a tab (the way the JQuery tabs worked originally)
- Only the selected tab is part of the tab order, the arrow keys are used to change the selected tab (as recommended in the key strokes section above)
There has already been some discussion about the ideal keyboard model for tabs, which describes the benefits and disadvantages of both options. Ideally this discussion should be reopened to reach concensus.
Potential issues:
- When a tab receives focus this needs to be indicated visually
- The selected tab needs to be indicated in a way that does not depend on color alone and remains visible in high contrast mode
Felix Nagel has created a plugin (ui.ariaTabs) that applies many of the recommendations above, and this should be used as a start for implementing accessibility changes to jquery.ui.tabs.
4.5 CSS & Theme
(Description of the CSS classes to be used for all states, how custom theming and Themeroller support will work.)
5 - Latest version of plugin:
http://code.google.com/p/jquery-ui/source/browse/tags/latest/ui/ui.tabs.js
6 - Open issues being discussed
(Use this area to place things that we're hashing out like featuresand options we're not sure we should include, questions about how this fits into UI and relates to other widgets and utilities, known problems, whether features should be broken across multiple releases, etc.)
Comments (16)
Richard D. Worth said
at 9:11 am on Dec 13, 2008
Should ui-tabs-hide be ui-helper-hidden? Is there any reason it needs to be tabs-specific?
scottjehl said
at 9:56 am on Dec 13, 2008
Seems it should have both, assuming it had the ui-tabs-hide class in previous releases. I'm not thrilled about the redundancy, but it follows what we're doing on other components with the addition of framework classes. Also, widget CSS needs a way to refer to elements without using the framework states (right?).
Richard D. Worth said
at 10:06 am on Dec 13, 2008
My first thought was that it should be renamed ui-tabs-hidden instead of ui-tabs-hide, for consistency with the framework classes. With as much as is already breaking in this release, I will tend toward cleanliness and consistency rather than backwards compatibility. But the more I thought about it, I can't see a use case for having a specific tabs-hidden class. It's just hidden. It's not hidden in some tabs-specific way. Or I guess that was my question ;) I think it's different than a case like disabled. Since disabled is a visible state, I think it's important to have both ui-draggable-disabled and ui-disabled (as an example). That way you can set a global disabled style with a widget specific override.
Richard D. Worth said
at 10:10 am on Dec 13, 2008
As far as consistency with other widgets, this is the only widget specific -hide or -hidden I saw, though other plugins hide things. Like accordion.
Jörn Zaefferer said
at 11:28 am on Dec 13, 2008
Accordion currently uses display:none, which probably should be replaced with ui-helper-hidden.
kpitn said
at 3:20 pm on Jan 13, 2009
Actually fxAutoHeight is no more an option of tabs, are you considering re integrate this option ?
Klaus Hartl said
at 11:43 am on Jan 25, 2009
Remember that it's not only about screen readers but also the ability to print.
Jan said
at 3:48 pm on Jun 1, 2009
If I understand it correctly 'ui-state-active' should be applied upon mousedown and should be removed on mouseup. Otherwise we don't have a state for mousedown. Tabs keep the active state upon click. And Accordion even uses the active state to indicate selected.
I find this inconsistency when I wanted to implement buttons clicks. Tabs, Accordion etc. should remove active state on mouseup and Accordion should use own 'ui-accordion-selected'. Now here is the other issue. Selected uses 'ui-selected'. Should we have general (and reusable) 'ui-state-selected' and each widget could customize it to its needs. Or the' tabs-selected', 'accordion-selected' approach is better.
sompylasar said
at 11:04 am on Aug 15, 2009
On Opera 9.65 (Win) ui.tabs sortable demo at http://jqueryui.com/demos/tabs/#sortable behaves glitchy: after drag the dropped tab jumps right and slightly down.
Please, test this case.
sompylasar said
at 11:08 am on Aug 15, 2009
Here comes the screenshot: http://img27.imageshack.us/img27/4807/scrjqueryuitabsglitch09.png
Matt Smith said
at 7:28 am on Oct 22, 2009
Is there any reason why the tabs widget does not include the fillspace option that the accordian has?
Bohdan Ganicky said
at 6:12 am on Jan 4, 2010
Is it possible to implement a "leave" callback? I have a situation in which I need to transfer information from one tab panel to another when switching between them. Now I have to do it manually. Another option could be to put a recently leaved tab information to callback's "ui" object.
Scott González said
at 11:19 am on Mar 18, 2010
Can't you do this with the select event?
fnagel said
at 4:07 am on Apr 15, 2010
Ive updated my accessibility "addon" for the UI tabs widget: http://github.com/fnagel/jQuery-Accessible-RIA
fnagel said
at 11:46 am on Jun 7, 2010
Some people requested history support for UI Tabs. Ive tested a few history plugins and i liked jQuery Addresss the most. It works fine cross brower and is well documented, so I decided to add Asuals history plugin to to my jQuery UI ARIA widgets (which includes a jQuery UI Tabs addon for accessibility features).
Please see links below for further information.
http://www.felixnagel.com/blog/artikel/2010/06/06/jquery-aria-with-browser-history-support-tabs-lightbox-and-sortable-tables/
http://www.asual.com/jquery/address/
Matt Travi said
at 3:01 pm on Jun 22, 2010
Although this is marked as complete, extending to include an option for vertical tabs is mentioned. Is there a time-line for this? Should something other than complete be used to mark the state of this widget if it is still expected to be extended?
You don't have permission to comment on this page.