Sexy Animated Tabs Using MooTools

Sexy Animated Tabs Using MooTools

One modern, attractive way of placing a lot of content into a little space is by using a tab system. This tutorial will show you how to create a sexy, animated tab system complete with CSS sprites, cookies, and animated tab swapping.


MooTools Tabs

Assumptions

There are a few assumptions and notes that we’re going into this system with:

  • We’ll be using the most recent version of MooTools: 1.2.4.
  • The client must support JavaScript.
  • We’ll be using PHP for any server-side scripting. Any server-side language of your choosing will also work its corresponding syntax/methods

The tutorial also assumes a basic knowledge of javascript. A tiny bit of MooTools or JavaScript framework experience will help.

The Plot

So how is this awesome system going to work? Here’s the basic outline:

  • When the page loads, we output two UL lists with list items: the first list contains the tabs, the second list contains the tab content items.
  • For each tab set we output, we check for a given cookie that could tell us which tab should be displayed based on the previous visit. If no cookie is present, we assume the first tab.
  • When the user clicks a tab, the current content item for that tab slides out of view and the new tab content slides in.
  • We save the index of the tab in a cookie for future loading purposes (i.e. we want to make the last-clicked-tab the first to display on the next page/visit.)

The system itself is pretty bulletproof. If the user doesn’t allow cookies, the starting tab for each list will always be 0.
If JavaScript support isn’t present, the tabs wont be seen on screen as we’ll display:none; them initially.

Step One: The HTML

The HTML to accomplish the tab system and corresponding content items is incredibly simple in structure.

<div class="tab-container">
	<ul id="tabs1" class="tabs">
		<li>Tab 1</li>
		<li>Tab 2</li>
		<li>Tab 3</li>
		<li>Tab 4</li>
	</ul>
	<div class="clear"></div>
	<ul id="contents1" class="tabs-content">
		<li>This is the content for tab 1.</li>
		<li>This is the content for tab 2.</li>
		<li>This is the content for tab 3.</li>
		<li>This is the content for tab 4.</li>
	</ul>
</div>

We will be modifying the above HTML with PHP later in this tutorial to create a more robust system.

MooTools Tabs

Step Two: CSS

As with any CSS and HTML combo, you may style the tabs and their content items however you’d like.
I’ve chosen to use Facebook-style CSS sprites for my example tabs.
Realize that you’ll want to style the following items in a specific fashion so that the system works:

  • The tab content items must have a height of 0 and their overflow’s hidden. That allows for all of the content items to be “hidden”, so to speak, when the page loads.
  • Between the “ul.tabs li a” and “ul.tabs li a.active” CSS selectors, you’ll want to assign the “active” selector a different look so that the user knows its’ the currently selected tab.
/* tabs structure */
.tab-container	{ width:320px; background:#eee; padding:5px 10px; }
ul.tabs			{ list-style-type:none; margin:0; padding:0; }
	ul.tabs li		{ float:left; margin:10px 5px 0 0; }
	ul.tabs li a	{ padding:5px 10px; border:1px solid #ddd; font-weight:bold; background:url(tab-sprite.jpg) 0 0 repeat-x; color:#000; text-decoration:none; }
	ul.tabs li a.active	{ border-color:#028433; background-position:0 -96px; color:#fff; } /* sprite! background position swap */
		ul.tabs li a.active:hover	{ text-decoration:none; cursor:default; }
	ul.tabs li:hover	{ text-decoration:underline; }
ul.tabs-content	{ margin:10px 0 0 0; padding:0; }
	ul.tabs-content li	{ height:0; overflow:hidden; margin:0; padding:0; }

/* clears floats */
div.clear		{ clear:both; }
		
/* ie fixes */
* html ul.tabs-content li { float:left; } /* ie6 */
*+ html ul.tabs-content li { width:99%; float:left; } /* ie7 */

Note that we need to implement a few Internet Explorer-specific fixes; ugly, but necessary.

MooTools Javascript Framework

Step Three: The MooTools Javascript

One of the great advantages of MooTools is the powerful Class system.
MooTools classes allow for flexible, organized, and extendable functionalities.
Our MooTools class will be called “TabSet.” Since the TabSet class performs many actions,
lets break down each part of the class.

The first line is always giving the class a name:

/* give the class a name */
var TabSet = new Class({

Next we need to create an object that will hold our class’ options:

	options: { //default tab options
		activeClass: 'active', //css class
		cookieName: '', //no name means no cookie
		cookieOptions: { //options for the cookie, if cookie's wanted
			duration: 30, //30 days
			path: '/'
		},
		startIndex: 0 //start with this item if no cookie or active
	},

Our options allow us to define:

  • activeClass: The CSS class that should be assigned to the currently-selected (or “active”) tab.
  • cookieName: The name of the cookie that will represent this tab set. If you don’t define a cookie name, cookies wont be used.
  • cookieOptions: An object that holds the options for the cookie.
  • startIndex: The tab to make active initially. Starts with 0. Overridden by the activeClass variable if a cookie is found.

With only three options in the class, TabSet would be considered a relatively simple class.

Next we implement two Options and Events:

Implements: [Options,Events],

Implementing Options and Events will allow us to correctly handle given options and
fire custom Load and Change events on our lists anywhere within the class.

Next we define the “initialize” method which runs upon creation of every instance of the class:

	initialize: function(tabs,contents,options) {
		//handle arguments
		this.setOptions(options); //mix the given options with the default options
		this.tabs = $$(tabs); //save the given tabs within the class
		this.contents = $$(contents); //save the given "contents" within the class
		//determine the "active" tab
		var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);  //decide the index that should be active initially
		this.activeTab = this.tabs[active].addClass(this.options.activeClass); //now identify the "active" tab
		this.activeContent = this.contents[active].setStyle('height','auto'); //identify the "active" content
		//run each tab/content combo through the "processItem" method which we'll see below
		this.tabs.each(function(tab,i) { this.processItem(tab,this.contents[i],i); },this);
		//tabs are ready -- fire the load event!
		this.fireEvent('load');
	},

Next comes the workhorse method of our TabSet class: processItem:

	processItem:function(tab,content,i) {
		var contentHeight = content.getScrollSize().y;
		//add a click event to the tab
		tab.addEvent('click',function() {
			//if it's not the active tab
			if(tab != this.activeTab) {
				//stopper
				if(e) e.stop();
				//remove the active class from the active tab
				this.activeTab.removeClass(this.options.activeClass);
				//make the clicked tab the active tab
				(this.activeTab = tab).addClass(this.options.activeClass);
				//tween the old tab content up
				//tween the new content down
				this.activeContent.set('tween',{
					onComplete:function() {
						this.activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
						//fire the tab change event
						this.fireEvent('change',[tab,content]);
					}.bind(this)
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height',0);
				//save the index to cookie
				if(this.options.cookieName) Cookie.write(this.options.cookieName,i);
			}
		}.bind(this));
	}
});

Here’s the basic outline of what the processItem method does:

  1. Accepts a matching tab, content item, and its index…
  2. Calculates the height of the content element.
  3. Adds a click event to the tab that:
    1. Validates that this tab isn’t already active (we don’t want to animate or change anything if they click the already-active tab)
    2. Removes the “active” CSS class from the current tab and adds it to the tab that was just clicked.
    3. Slides the current tab’s content out of view, then slides the new content into view. The “change” event is fired when the animation is complete.
    4. Saves the new tab’s index to the cookie so that when the user reloads the page or goes to another page, the new tab will be selected initially.

And now a sample usage of our class:

window.addEvent('domready',function() {
	var tabset = new TabSet($$('#tabs1 li a'),$$('#contents1 li'),{
		cookieName: 'demo-list'
	});
});

We provide our instance the tab LI A’s and the content LI’s. We also provide the optional options argument. That’s how easy it is to use this class! Here’s the complete class with usage:

/* class */
var TabSet = new Class({
	options: {
		activeClass: 'active', //css class
		cookieName: '',
		cookieOptions: {
			duration: 30, //30 days
			path: '/'
		},
		startIndex: 0 //start with this item if no cookie or active
	},
	Implements: [Options,Events],
	initialize: function(tabs,contents,options) {
		//handle arguments
		this.setOptions(options);
		this.tabs = $$(tabs);
		this.contents = $$(contents);
		//determine the "active" tab
		var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);
		this.activeTab = this.tabs[active].addClass(this.options.activeClass);
		this.activeContent = this.contents[active].setStyle('height','auto');
		//process each tab and content
		this.tabs.each(function(tab,i) {
			this.processItem(tab,this.contents[i],i);
		},this);
		//tabs are ready -- load it!
		this.fireEvent('load');
	},
	processItem:function(tab,content,i) {
		var contentHeight = content.getScrollSize().y;
		//add a click event to the tab
		tab.addEvent('click',function(e) {
			//stop!
			if(e) e.stop();
			//if it's not the active tab
			if(tab != this.activeTab) {
				//remove the active class from the active tab
				this.activeTab.removeClass(this.options.activeClass);
				//make the clicked tab the active tab
				(this.activeTab = tab).addClass(this.options.activeClass);
				//tween the old tab content up
				//tween the new content down
				this.activeContent.set('tween',{
					onComplete:function() {
						this.activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
						//fire the tab change event
						this.fireEvent('change',[tab,content]);
					}.bind(this)
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height',0);
				//save the index to cookie
				if(this.options.cookieName) Cookie.write(this.options.cookieName,i,this.options.cookieOptions);
			}
		}.bind(this));
	}
});
/* usage */
window.addEvent('load',function() {
	var tabset = new TabSet($$('#tabs1 li a'),$$('#contents1 li'),{
		cookieName: 'demo-list'
	});
});	
MooTools Cookies

Step Four: PHP / HTML

Remember how I said we’d be modifying our original HTML with PHP? Now’s the time. Since we may
have a cookie set for our TabSet, we should attempt to detect that when we output the tab HTML.
Why? Because we want the tabs to load in smoothly. We also want to accommodate for users that don’t have JavaScript or cookies enabled.
Without this PHP, you may notice a slight “jump” in the active content area.

<?php
	/*
		Removes a desired variable from the querystring
		Credit:  http://www.addedbytes.com/code/querystring-functions/
	*/
	function remove_querystring_var($url, $key) { 
		$url = preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
		$url = substr($url, 0, -1);
		return ($url); 
	}
	
	/* generate the urls */
	$demo_tabs_url = remove_querystring_var($_SERVER['REQUEST_URI'],'demo-list');
	$demo_tabs_url.= (is_numeric(strpos($demo_tabs_url,'demo-list')) ? '&' : '?').'demo-list=';
	
	/* current tab */
	$current_tab = isset($_COOKIE['demo-list']) ? (int) $_COOKIE['demo-list'] : (isset($_GET['demo-list']) ? (int) $_GET['demo-list'] : 0);
	
?>

<div class="tab-container">
	<ul id="tabs1" class="tabs">
		<li><a href="<?php echo $demo_tabs_url.'0'; ?>" <?php echo $current_tab == '0' ? ' class="active"' : ''; ?>>Tab 1</a></li>
		<li><a href="<?php echo $demo_tabs_url.'1'; ?>"  <?php echo $current_tab == '1' ? 'class="active"' : ''; ?>>Tab 2</a></li>
		<li><a href="<?php echo $demo_tabs_url.'2'; ?>"  <?php echo $current_tab == '2' ? 'class="active"' : ''; ?>>Tab 3</a></li>
		<li><a href="<?php echo $demo_tabs_url.'3'; ?>"  <?php echo $current_tab == '3' ? 'class="active"' : ''; ?>>Tab 4</a></li>
	</ul>
	<div class="clear"></div>
	<ul id="contents1" class="tabs-content">
		<li <?php echo $current_tab == '0' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1. This is the content for tab 1.</li>
		<li <?php echo $current_tab == '1' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2. This is the content for tab 2.</li>
		<li <?php echo $current_tab == '2' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3. This is the content for tab 3.</li>
		<li <?php echo $current_tab == '3' ? ' style="height:auto;"' : ''; ?>>This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4. This is the content for tab 4.</li>
	</ul>
</div>

Step Five: PHP: Accommodating For Users Without Javascript or Cookies

Some users don’t enable JavaScript or cookies for security purposes. We still want our system to work for them though. If you recall from the previous block of code,
we’re using links with a querystring key of “demo-list” to denote a change in tab. The following block of PHP at the top of the page (before ANY output) will
help us change the cookie value to the requested tab.

<?php
	/* handle the cookies */
	if($_GET['demo-list']) {
		/* set the new cookie */
		setcookie('demo-list',(int) $_GET['demo-list'],time()+60*60*24*30,'/'); //30 days
		if($_COOKIE['demo-list']) {
			header('Location: '.remove_querystring_var($_SERVER['REQUEST_URI'],'demo-list'));
			exit();
		}
	}
?>

Note that we only refresh the page if we can verify that the cookie has been set. If the cookie hasn’t been set, the user has their cookies disabled.

MooTools Cookies

Mission Accomplished!

Here’s a quick summary of the benefits of the MooTools TabSet class:

  • Our class implements Events so that we may create custom events and event handlers.
  • The layout of the entire system is controlled completely by simple HTML and CSS.
  • The use of cookies to remember the previous tab is great usability improvement.
  • The very class that it’s a MooTools class allows for it to be easily implemented from project to project.

The Inline MooTools Javascript

I’ve always advocated coding a desired MooTools functionality “inline” before turning it into a class. Here’s the inline MooTools JavaScript code:

$$('ul.tabs').each(function(tabList) {
	//get the content list
	var tabContentList = tabList.getNext('ul.tabs-content'), 
		//get the name of the cookie, which is the "title" attribute of the tab list
		cookie = 'demo-list',
		//the start tab index
		startIndex = Cookie.read(cookie) || 0,
		//get the actual tab LI items
		tabs = tabList.set('title','').getElements('li'), 	
		//get the content LI items
		lis = tabContentList.getElements('li'),
		//the tab (LI) that is currently active
		activeTab = tabs[startIndex].addClass('active'),
		//the content LI that is currently active
		activeContent = lis[startIndex].setStyle('height','auto');
	//for every tab within this tab/content relationship...
	tabs.each(function(tab,i) {
		//stopper
		if(e) e.stop();
		//calculate the respective content item's height
		var content = lis[i], contentHeight = content.getScrollSize().y;
		//add the click event to the tab which...
		tab.addEvent('click',function() {
			//if it's not the currently activated tab...
			if(tab != activeTab) {
				//add and remove the active class from old vs. new tab
				activeTab.removeClass('active');
				(activeTab = tab).addClass('active');
				//start the wipe up, wipe down effect
				activeContent.set('tween',{
					onComplete:function() {
						activeContent = content.fade('in').set('tween',{ onComplete: $empty }).tween('height',contentHeight);
					}
				}).setStyles({
					height: contentHeight,
					overflow: 'hidden'
				}).fade('out').tween('height','0');
				//write to cookie
				Cookie.write(cookie,i);
				//fin!
			}
		});
	});
	//fire click event 	
	activeTab.fireEvent('click');
});

Notice that all of the “var” statements at the top either become arguments or options for the class. The transition from inline MooTools JavaScript to a class is extremely simple!

MooTools Tabs

Have Improvement Ideas?

Have more ideas for this class? Be sure to share them in the comments below!

Write a Plus Tutorial

Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We’re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you’re of the ability, please contact Jeffrey at nettuts@tutsplus.com.

Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

Write a PLUS tutorial

Tags: MooTools
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • JimmyJames

    No demo?

    • http://www.jeffrey-way.com Jeffrey Way

      Just updated with the demo. :)

  • http://parenting.pl Marcin

    I have a great improvement idea… please rewrite this tutorial using jquery :-).

    • http://envexlabs.com Matt Vickers

      Great learning exercise, re-write in jQuery yourself :P

    • alex

      noob

    • http://kreativtstudio.no Roaa

      it’s not that hard converting this to jQuery. Read some tutorials, JW also got some awesome tutorials for jQuery beginners.

    • Ryan

      Copy / paste goon.

    • http://www.wdonline.com Jeremy McPeak

      I’ll take MooTools over jQuery anyday.

  • Brad Benvenuti

    Cool, but a demo would definitely help.

  • http://davidwalsh.name David Walsh

    It doesn’t look like Jeffrey added the demo. You can check that out here:

    http://davidwalsh.name/dw-content/mootools-tabs.php

  • http://www.hainghiem.com hainghiem

    Good Tutorial. Thanks for sharing

  • http://null Rodolfo

    Great tut, but isn’t this much more using jQuery UI? For example, you can achieve exacly this “Sexy Tabs” with just a single line of code:

    $(document).ready(function() {
    $(‘#tabs’).tabs({ fx: { height: ‘toggle’, slide: ‘true’ } });
    });

    Where tabs is a div with the following content:

    First
    Second

    Hi! I’m First Tab’s content!

    Hi! I’m Second Tab’s content!

    Ta dá! jQuery UI will recognize all the elements inside #tabs and make it look just like the “Super Sexy Tabs with Mootols” but just with a single code line :D

    Eitherway, as always, great tut (:

    • http://www.complimedia.com Montana Flynn

      It is nice to understand how the code works as opposed to relying on the work of others. This way you can feel very comfortable writing and modifying code.

  • http://twitter.com/KGTheNerd Karthik

    Lovely, looks awesome I will try this out :)

  • trollhammer

    who uses mootools?

    • Hoax

      Lots of developers out there, Based on project some times mootools get things done much faster than jQuery does for me.

    • alex

      I think a lot of people wonder why user Mootools instead of Jquery. In simple terms Mootools is a very powerful Object Oriented JS framework. It has the power to build very advanced web applications. Mootools is generally for those already very familiar with Javascript. In contrast, JQuery has been adopted widely by a lot people that are not very strong in JS (and some who are) because it makes it easy for designers comfortable with CSS to transition to JS.

    • slik
      • http://www.urbanvideos.tv alan

        Most of the Joomla folks uses mootools.Mootools is easy as JQ and in some cases faster and got better performance.

  • http://null Rodolfo

    Today is not my day..

    First
    Second

    Hi! I’m First Tab’s content!

    Hi! I’m Second Tab’s content!

    Be aware of remove the spaces between the

  • YAR ZAR

    Another yet nice mootool tuts..

  • dreake

    David in nettuts – sounds great

  • http://bvk.name Boris

    Awesome work David!

  • http://jhaygamba.com Jhay Gamba

    Amazing tutorial by DAVIDW!!

    Yeah, David In Nettuts rocks!

    Thanks

    JHAY

  • Alelo

    David 4 Moosident!

    nice tut how about an ajax version? :) 4 improvement

  • http://sonergonul.com Soner Gönül

    Wow !

    That’s great !

    Thanks !

  • Jacek

    Doesn’t work without JS. All the time I see the tab I have selected with JS enabled.
    Instead of using cookie you may try use # in URI just as gmail does – it’s not hard to implement and it improves accessibility. Now if I send a link from one tab to my friend he will see tab1 instead of, for example tab4. With # in URI – he will receive link to the tab I am viewing.

    • http://davidwalsh.name David Walsh

      Try again. I updated the demo to match exactly what was in this post.

      • Jacek

        Works better :-) But I can’t go from tab4 to tab1 – I still see tab4.

  • http://meiocodigo.com Fábio M. Costa

    An improvement:

    set(‘tween’, {link: ‘cancel’, onComplete….});

    With “link: ‘cancel’” theres no flickering when you quickly click on two tabs.

  • http://www.seowisedesigns.com Yheng

    Does the same trick with jQuery but this one is great too! Gives me more ideas after seeing this tuts.. Thanks David ;)

  • http://bloggerzbible.blogspot.com/ Bloggerzbible

    Is really sexy. Thanks

  • http://theyppublishing.com Yvonne Wu

    Reallyy nice! Thanks!

  • http://fwebde.com/ Eric B.

    Looks cool. But the transition is soooo long, it will either be annoying if it’s too slow, or ugly if it’s too fast.

  • http://www.jordanwalker.net/index.php Jordan Walker

    Sleek and Effective

  • Jose Perales

    Good Tutorial. Thanks for sharing

  • http://www.Thejoomlers.co.uk Sandya

    Nice post !

  • http://www.selog.in Nitesh

    nice tuts…. thanks for sharing i will try tat out. :)

  • http://www.donothavedomainyet.com Eugene

    Why in step one as I understand there are three colors for button?

  • http://www.camp26.biz Eko Setiawan

    Wos..this tutorial can we use, for our next template…we’ll try it first
    Thanks…

  • http://www.foxyturkey.com Yigit Ozdamar

    Cool! I think i will use this one on my blog. Thanks mate!

  • http://blog.computer-service-mallorca.com Michael Pehl

    David FTW! Another nice tut by his majesty :)

    Thank you for sharing!

  • Mike

    This tutorial is not awesome. It is a ridiculously large hammer to crack a small nut. Let’s have neat solutions please.

    • http://www.danwellman.co.uk Dan Wellman

      I disagree, the tutorial is an excellent introduction to writing classes in Mootools as opposed to just writing code that does stuff. Creating the tabs is just an excercise to reinforce writing code as a class, a vehicle for understanding…

    • http://davidwalsh.name David Walsh

      This tutorial is the epitome of what MooTools is about: writing code that is portable, flexible (it may be extended by subclasses), and easy to read. It also needed to be modified to work for users without cookies.

  • xTraCD

    This tutorial has already been done before in a more efficient way…
    Just with regular jQuery instead.

    http://net.tutsplus.com/tutorials/javascript-ajax/create-a-tabbed-interface-using-jquery/

    why are there so many tutorials that teach the same thing with the same language?

    • http://www.complimedia.com Montana Flynn

      Did you not read the tutorial? David explained how to get tabs to work with javascript disabled and with cookies. He also used MooTools instead of jquery. Plus he gave an example of css sprites.

      Why do people complain about the great posts here and elsewhere? Can’t you appreciate the logic and thought that went into this tutorial? Sure it does what other tuts do, but it portrays the process behind the effect. That is worth more than the effect itself.

    • http://www.aftertheone.com Matthew Booth

      @ Montana – Because his name begins with ‘xTra’ he thinks he is a l33t haxor lol

  • jem

    Nice tutorial.

    I notice this a lot with your code (which is just your style), but you seem to try and pack as much into one place as possible. I prefer to branch the functionality of classes into more meaningful methods that are built to do specific things. Makes reusing code a lot easier when a method is made to sort of “stand alone.”

    Mootools is fantastic. I’ve slowly started warming up to jQuery too, though in most cases it just reinforces my choice of using Mootools.

    @Rodolfo – you’re comparing the code of a constructor from jQuery UI to a class definition from Mootools. Obviously you could use jQuery UI (or any plugin that someone else has created) and learn nothing, or write your own code and become a better programmer.

  • johnny

    mootools is wack…

    • http://www.aftertheone.com Matthew Booth

      you’re whack

      • http://davidwalsh.name David Walsh

        Agreed. :)

  • http://tr.im/mewC Rahul – Web Guru

    This is super cool tools. Nice jQuery effect.

  • Colin Robertson

    It’s a cool effect but it’s not tabs. They’re buttons.

    Fair enough it doesn’t make a huge difference but for a web development to be making that mistake is pretty surprising

    • http://davidwalsh.name David Walsh

      Tabs don’t need to fall outside the content are to be tabs — it’s basic positioning. As mentioned in the article, you may style these items any way you’d like. If you choose to place the tabs above the content wrapper, go for it.

  • Raoul

    HAHAHA “sexy” again ^^

  • Mike

    very nice, I’d like to learn mooTools.. any suggestions about some place to start?

  • hamburger

    hello, great sexy thing

    there is a bug in the inline version:
    //stopper
    if(e) e.stop();
    it has to be placed in line 24;

    • http://davidwalsh.name David Walsh

      Good catch hamburger — I added the events part at the end.

  • hamburger

    hello again,
    can someone explain what the lame ie fixes do. (especially the +html)
    without, it makes with every tab a bigger gap to the content.
    with: i cant adapt it to my layout

    /* ie fixes … lame */
    * html ul.tabs-content li { float:left; } /* ie6 */
    *+ html ul.tabs-content li { width:99%; float:left; } /* ie7 */

    i’am using ie7
    thanx

    • http://www.nbatdigital.co.uk web design kent

      Great Read! Many Thanks for the article

  • http://davidwalsh.name David Walsh

    The IE fixes fix positioning for each of those browsers. Why? Because IE has a mind of its own.

  • http://www.bogdanpop.info Bogdan Pop

    There’s a similar tabs effect achieved with jQuery, described in this tutorial at http://www.freelancermagazine.com/building-an-awesome-navigation-menu-with-jquery-part-2/ . The demo’s over here: http://demos.webia.info/fancy_menu_v2/

  • http://lickynee.com lickynee

    This is a great tutorial! Just getting to know MooTools.

  • Martin

    Could anybody help me with this script?
    I need the possibility to “open/close” the tabs – and that all tabs are closed at the beginning when the Site loads…

    Please!!! I really need help with this!!!

    Thank you

  • Duarte

    Hello,
    excellent tutorial.

    But I tried to embed a youtube video on the content of one menu and it keeps showing in all of them.

    Thank you

  • Otto T Freeman
  • Moey

    I have it working fine for the most of it except when i want to add a list in the actual body of the that is being used to display the content. This breaks the whole thing. How do i add a bullet list in as the content without it thinking im ending the ??

    Thanks.

  • http://www.wallpapers-foothball.net Alexandar

    Hello this is very nice tutorial,but i want this to be made without php.Is this possible?

  • Bruno

    Hi and thanks for the great tutorial!

    But how can I remove the whole cookie stuff code. I’d just like to have the tabs starting with the first one when someone is loading the site.

    Thaks!

  • Binyamin

    It has cookie bug. Try to open some tab and after make browser refresh.

  • Josh

    An issue I am running into is when I have a div inside one of the tabs content where I do an ajax call to populate the div. The ajax works fine, but when I switch tabs and then comback, the content height is incorrect.

    I have been looking through the code trying to find a tweak, with no luck. Any suggestions?