HTML/DOM Tabbed Panes
Tabbed interfaces are a staple of UI development, yet are missing from HTML. Fortunately, they’re relatively simple to implement using a little cross-browser JavaScript and HTML DOM.
Solution
A tabbed pane in HTML can be implemented in two parts. The first, a <TABLE> containing the row of tabs. The second, a series of <DIV>s, one for each content pane. The table will always remain visible while the div tags will be displayed one at a time, dependent on which tab is selected. See Figure 1.
tabCount = 3;
function activateTab(i) { document.getElementById( "tab-left:"+i ).src="article-2003.06.24-html_tabs/tab-left_active.gif" mce_src="article-2003.06.24-html_tabs/tab-left_active.gif" ; document.getElementById( "tab-bg:"+i ).style.background="url(article-2003.06.24-html_tabs/tab-bg_active.gif)"; document.getElementById( "tab-right:"+i ).src="article-2003.06.24-html_tabs/tab-right_active.gif" mce_src="article-2003.06.24-html_tabs/tab-right_active.gif" ; document.getElementById( "tab-body:"+i ).style.display='block'; } function deactivateTab(i) { document.getElementById( "tab-left:"+i ).src="article-2003.06.24-html_tabs/tab-left_inactive.gif" mce_src="article-2003.06.24-html_tabs/tab-left_inactive.gif" ; document.getElementById( "tab-bg:"+i ).style.background="url(article-2003.06.24-html_tabs/tab-bg_inactive.gif)"; document.getElementById( "tab-right:"+i ).src="article-2003.06.24-html_tabs/tab-right_inactive.gif" mce_src="article-2003.06.24-html_tabs/tab-right_inactive.gif" ; document.getElementById( "tab-body:"+i ).style.display='none'; } function changeActiveTab(i) { for( j=0; j < tabCount; ++j ) { if( j==i ) { activateTab(j); } else { deactivateTab(j); } } }
1.1. Overview of the DOM Core Interfaces
This section defines a set of objects and interfaces for accessing and manipulating document objects. The functionality specified in this section (the Core functionality) is sufficient to allow software developers and web script authors to access and manipulate parsed HTML and XML content inside conforming products. The DOM Core API also allows creation and population of a Document object using only DOM API calls; loading a Document and saving it persistently is left to the product that implements the DOM API.
The Tab Table
Each tab is made of three <TD> elements. One for the left side, one for the center, and
one for the right. Both the left and the right elements contain an image. The center contains the
HTML for the tab text, or whatever you wish to insert. It also has a background image, to complete the
illusion. A simplified, single tab example is shown here:
<div align="center"><table border="0" cellspacing="0" cellpadding="0"><tr>
<td width="6"><img xsrc="tab-left_active.gif" border="0" id="tab-left:0"></td>
<td align="center" style="cursor: pointer; background: url(tab-bg_active.gif)"
onClick="changeActiveTab(0)" id="tab-bg:0">
<i>This is the first tab...</i>
</td>
<td width="6"><img xsrc="tab-right_active.gif" border="0" id="tab-right:0"></td>
</tr></table></div>
You can see the numbered tab ids in red and the active/inactive images in blue. You can also see the center tab's onClick event, calling this JavaScript method:
tabCount = 1;
function changeActiveTab(i) {
for( j=0; j < tabCount; ++j ) {
if( i==j ) { activateTab(j); }
else { deactivateTab(j); }
}
}
This simply iterates through all the tabs, turning off all but the one selected. The methods that activate and deactivate each tab are here:
function activateTab(i) {
document.getElementById( "tab-left:"+i ).src="tab-left_active.gif" mce_src="tab-left_active.gif" ;
document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_active.gif)";
document.getElementById( "tab-right:"+i ).src="tab-right_active.gif" mce_src="tab-right_active.gif" ;
document.getElementById( "tab-body:"+i ).style.display='block';
}
function deactivateTab(i) {
document.getElementById( "tab-left:"+i ).src="tab-left_inactive.gif" mce_src="tab-left_inactive.gif" ;
document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_inactive.gif)";
document.getElementById( "tab-right:"+i ).src="tab-right_inactive.gif" mce_src="tab-right_inactive.gif" ;
document.getElementById( "tab-body:"+i ).style.display='none';
}
You'll notice the last line in each method changes the style attribute of the associated tab pane.
The Content Panes
The content panes are real simple. Here is an example containing two tabs.
<style>
DIV.tab-body {
background: white;
border: 1px solid black;
padding: 10px;
}
</style>
<div align="center"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td height="8" background="tab-hr.gif"></td></tr>
</table></div>
<div id="tab-body:0" class="tab-body" style="display: block;">
CONTENT - TAB 1
</div>
<div id="tab-body:1" class="tab-body" style="display: none;">
CONTENT - TAB 2
</div>
You'll notice that the first <DIV> tag is "display:BLOCK", while the second is "display:NONE". Information on the display CSS element can be found here, but for our use you only need to know that DIV tags default to block when they're displayed, and like any HTML element can be removed from the render stream by setting it to none. So basically, all the panes are there on the page at the same time, but only one is rendered at any given moment.
Future Work
There is a lot of repeating HTML code to implement these tabs, and you may want to implement them more than once in your project or on your web site. This just begs to be automated in PHP, Perl or Java. I'll leave the implementation of that up to the reader, but here's one possible interface:
<% org.kered.htmlet.TabBuilder tb = new org.kered.htmlet.TabBuilder(); %>
<% tb.addTab( "tabA", "<i>This is the first tab...</i>" ); %>
<% tb.addTab( "tabB", "Tab #2" ); %>
<% tb.addTab( "tabC", "<img xsrc='emoticon.gif'>" ); %>
<% tb.setActiveTab("tabA"); %>
<%= tb.init() %>
<%= tb.startTab("tabA") %>
CONTENT - TAB 1
<%= tb.endTab() %>
<%= tb.startTab("tabB") %>
CONTENT - TAB 2
<%= tb.endTab() %>
<%= tb.startTab("tabC") %>
CONTENT - TAB 3
<%= tb.endTab() %>
The HTML code for these examples can be found here.
All code is licenced under the GPL.
If you would like the code under an alternate license, please ask.














March 28th, 2007 at 5:09 pm
Concerning: HTML/DOM Tabbed Panes
Thanks for working this issue out. Pretty cool. But where are the images that go with the code? I think your image links are broken.