XForms/Horizontal File Tab Menu Highlighted

Motivation

edit

Complex web forms frequently break tasks up into multiple views that can be navigated by the user. These views are access by a set of "file tabs" at the top of a screen. But the user needs feedback on which tab is the current tab and we would like to do this without resorting to complex JavaScript.

Approach: Use the CSS-3 :target pseudo element

edit

This example uses the CSS-3 :target pseudo element to highlight the selected tab. This tag is associated with the part of a web page that is specified by the label. For example you can append a label to a URL like the following:

http://www.example.com/mypage.html#mylabel

Note: This works only in CSS-3 and will not work under IE-6.

Note that this example is very similar to the prior example but it uses a HTML anchor instead of a trigger.

Screen Image

edit
 
Screen image with second tab selected

Sample Program

edit
<html
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:xf="http://www.w3.org/2002/xforms"
   xmlns:ev="http://www.w3.org/2001/xml-events">
   <head>
      <title>CSS: a tabbed interface</title>
      <style type="text/css">
@namespace xf url("http://www.w3.org/2002/xforms");

/* Put the tab divs all on one line */
div.horiz-tabs-menu div {
  display: inline;
}

/* style each individual tab */
div.horiz-tabs-menu div a {
    color: black;
    border: 0.1em outset #BBB;	/* Make it look like a button */
    border-bottom: 0.1em solid #CCC;
    font-weight: bold;
    font-family: Helvetica, sans-serif;
    text-decoration: none;
    margin-right: 5px;
    padding: 0.2em;
    /* round the top corners – works under FireFox */
    -moz-border-radius: .5em .5em 0em 0em;
 }

/* Make non-selected tabs appear in the background */
div.horiz-tabs-menu div:not(:target) a {
   border-bottom: none;		/* Make the bottom border disappear */
   background: #999;
}

/* Make the selected (targeted) item or default selection to appear on top */
div.horiz-tabs-menu div:target  a {
   border-bottom: 0.1em solid #CCC;   /* Visually connect tab and tab body */
   background: #CCC;                          /* Set active tab to light gray */
}

/* set non-selected tabs to dark gray */
div.horiz-tabs-menu div:not(:target) a {
   border-bottom: none;	/* Make the bottom border disappear */
   background: #999;           /* Set inactive tabs are dark gray */
}

xf|switch xf|case div {
  background: #CCC;		/* Light gray */
  padding: 0.3em;		/* Looks better */
}
</style>
   </head>
   <body>
      <div class="horiz-tabs-menu">
         <div id="tab1">
            <a  href="#tab1">Tab 1
	         <xf:toggle case="case-1" ev:event="DOMActivate" />
            </a>
         </div>
         <div id="tab2">
            <a href="#tab2">Tab 2
	         <xf:toggle case="case-2" ev:event="DOMActivate" />
            </a>
         </div>
         <div id="tab3">
            <a href="#tab3">Tab 3
	         <xf:toggle case="case-3" ev:event="DOMActivate" />
            </a>
         </div>
      </div>
      <xf:switch>
         <xf:case id="case-1" selected="true()">
            <div>
            1111111111 1111111111 1111111111
            1111111111 1111111111 1111111111
            1111111111 1111111111 1111111111
            1111111111 1111111111 1111111111
            </div>
         </xf:case>
         <xf:case id="case-2">
            <div>
            2222222222 2222222222 2222222222
            2222222222 2222222222 2222222222
            2222222222 2222222222 2222222222
            2222222222 2222222222 2222222222
            </div>
         </xf:case>
         <xf:case id="case-3">
            <div>
            3333333333 3333333333 3333333333
            3333333333 3333333333 3333333333
            3333333333 3333333333 3333333333
            3333333333 3333333333 3333333333
            </div>
         </xf:case>
      </xf:switch>
   </body>
</html>

Discussion

edit

The selected file-tab should highlight in a light gray. The other menus should be in a dark gray and appear to be more in the background. The content associated with each tab should be visible.

Note that if you want the first tab to highlight on page load, you must use the #tab1 in the URL.

Possible areas for improvement

edit

Although this "hack" works and it does get rid of some commonly occurring JavaScript, it is still lacking in several ways.

  1. You can only have a single selected tab on a page.
  2. There is no way to highlight the initial tab without adding the label in the URL
  3. The label gets stuck in the URL and makes things like bookmarking problematic

Ideally XForms would include a :selected pseudo element that would allow you to apply a different style to a selected item within a group. Perhaps someone will do this as a custom control to FireFox.

I should also note I have tried to add a class to the tab1 div called "selected" and added it to the CSS to select it initially, but then it does not unselect when I select a different tab. I can't find an easy way to dynamically add or remove a class to an element in the body of an XForm. There does not appear to be a <xf:class add="selected"> command. Perhaps that will be added to future version of the XForms specification.

Other Examples

edit

The following example shows how tab elements can be stored within a model: Kurt Cagle Tab Example

Next Page: Vertical Menu | Previous Page: Horizontal File Tab Menu
Home: XForms