Dynamic CSS Tabs in Symfony

July 9, 2007 – 6:13 am

We are introducing a tabbed menu interface for ThemBid.com and following are the requirements and the step by step instructions used to make it happen. Although I hacked this in Symfony, it is easy to use any PHP framework.

Here are the parameters:

  • Easily be able to change the colors easily
  • Allow for sub-navigation
  • Use plain text for the titles of the tab
  • Use a different background and text color for the active tab
  • Pre-load the rollovers
  • The menu should be semantically correct (i.e. in a html list format with all design in the CSS)
  • No Javascript necessary
  • Degrade gracefully
  • No more than three graphics files needed
  • Re-usable

First, I will show the final product (six tabs) and give you the necessary images so that you can try it out. Secondly, I will show you how to automatically generate the menu and choose the selected tab in PHP within the Symfony framework. This solution is based on the Sliding Door technique with dynamic width and a rollover effect.

The HTML

The first step is to define what the menu links will be in the view. The final generated HTML is as follows:


The CSS

#navigation_tabs
{
  padding: 0px;
  margin: 0px;
  height: 76px;
  width: 827px;
}
#tab_container
{
  padding: 0px;
  margin: 0px;
  height: 37px;
}
/* This is for the sub-navigation */
.menu_bg
{
  padding: 0px;
  padding-bottom: 6px;
  margin: 0px;
  height: 24px;
  width: 827px;
  background: url("/images/navigation_menu_bg.png") 0 0 no-repeat;
}
#tabs{
  float: left;
  width: 100%;
  font-size: 93%;
  line-height: normal;
}
#tabs ul{
  margin: 0;
  padding: 10px 10px 0;
  list-style: none;
}
#tabs li{
  display:inline;
  margin:0;
  padding:0;
}
#tabs a{
  float:left;
  background:url(/images/button_top_left.png) no-repeat left top;
  margin:0;
  width:.1em;
  margin-left: 8px;
  padding:0 0 0 8px;
  text-decoration:none;
}
#tabs a span {
  float:left;
  display:block;
  background:url(/images/button_top_right.png) no-repeat right top;
  padding:7px 15px 4px 6px;
  font-weight:bold;
  /* Color of the text for inactive tabs */
  color: #505050;
}
/* Commented Backslash Hack
    hides rule from IE5-Mac \*/
#tabs a span {
  float:none;
  text-decoration: none;
}
/* End IE5-Mac hack */
#tabs > ul a {
  width:auto;
}
#tabs a:hover span {
  color: white;
}
#tabs a:link {
  text-decoration: none;
}
#tabs a:hover {
  background-position:0% -28px;
  text-decoration: none;
}
#tabs a:hover span {
  background-position:100% -28px;
  text-decoration: none;
}
#tabs #selected_tab a{
  background:url(/images/button_top_left.png) no-repeat left top;
  background-position:0% -28px;
}
#tabs #selected_tab a span {
  background:url(/images/button_top_right.png) no-repeat right top;
  background-position:100% -28px;
  color: #FFFFFF;
}

Graphic Files

button_top_left.png
button_top_right.png
navigation_menu_bg.png

PHP Code

I call the tab menu using the following function call:


myView is a class located at lib/myView.class.php so that the code can be shared among applications. The parameter to the getMenuTabs function tells us what tab is active. Leave it blank to have no tab active.

Here is the definition of the getMenuTabs function:

public static function getMenuTabs( $location )
{
  $menu = "


\n";
  echo $menu;
}

This is the function that generates the HTML (also located in the MyView class):

//$links is an array whose key is the text that you want the button to display and the value is the URL
//$params is an array that allows for additional parameters such as javascript and class or id definitions. \
//  The key must be the same as its corresponding $links key
// $container defines the id for the div that holds all the tabs
public static function create_button( $links, $params="", $container="" )
{
  $button = "
\n"; $button .= "
\n
    \n"; foreach( $links as $key => $value ){ if( !$params ) { $button .= "
  • ".link_to("$key", "$value")."
  • \n"; } else { if( isset($params[$key]) ) { $p = $params[$key]; } else { $p = ""; } $button .= "
  • ".link_to("$key", "$value")."
  • \n"; } } $button .= "
\n
\n
\n"; return $button; }

I am always interested in improving my programming skill, so all feedback is welcome. Happy coding…

UPDATE: The tabbed interface is now live at ThemBid.com.

  1. 4 Responses to “Dynamic CSS Tabs in Symfony”

  2. Very nice read!

    By Jose Lopez on Jul 9, 2007

  3. Very nice! I was just wondering - is the code shown here “public domain”? Thanks -
    - Andy

    By Andy on Jul 9, 2007

  4. Andy,

    Yes, go ahead and have fun with it.

    By ethomas on Jul 9, 2007

  5. I would suggest to use components instead. Components let you separate the logic and views in a nice way, just like a normal action :)

    By Pierre on Jul 24, 2007

Post a Comment