jQuery Tabs Plugin | My first jQuery Plugin

By | May 5, 2011

So building on the previous post Pure Javascript Tabs with HTML 5 and CSS3 I have decided to make my first jQuery plugin which is just going to be the tabbed navigation that we created previously. We’re going to use the same HTML5 page but with the help of some more CSS styling we’re going to create 3 UI styles that can be created easily with the plugin. So do you want to see the HTML again? Oh go on then if you like.
View Demo 1View Demo 2Download Source

The HTML






jQuery, HTML 5 & CSS3 Tabs



  • Page 1
  • Page 2
  • Page 3

Page 1

Pellentesque habitant morbi tristique...

Page 2

Pellentesque habitant morbi tristique...

Page 3

Pellentesque habitant morbi tristique... luctus, metus.

So nothing really new here (if you checked out my previous post especially) the only thing you may have noticed is the name of my plugin. Yes I’ve called it AcidTabs, I just couldn’t help myself.(That’s the reason for the smiley face on the feature image.) So as before the main tab wrapper is called #tabContainer and then below that we have list for the tabs themselves and then separate div’s with the tab content in.

The CSS

* {
	margin:0;
	padding:0;
}

body {
	background:url(../../images/background.png) top left;
	font: .8em "Lucida Sans Unicode", "Lucida Grande", sans-serif;
}

h2{ 
	margin-bottom:10px;
}

#wrapper{
	width:720px;
	margin:40px auto 0;
}

#wrapper h1{
	color:#FFF;
	text-align:center;
	margin:20px 0;
}

#wrapper a{
	display:block;
	font-size:1.2em;
	padding-top:20px;
	color:#FFF;
	text-decoration:none;
	text-align:center;
}

.one {
	width:700px;
	padding:15px;
	background-color:#2e2e2e;
	-moz-border-radius: 4px;
	border-radius: 4px; 
}

.one > .tabs{
	height:30px;
}

.one > .tabs > ul{
	font: 1em;
	list-style:none;
}

.one > .tabs > ul > li{
	margin:0 2px 0 0;
	padding:7px 10px;
	display:block;
	float:left;
	color:#FFF;
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
	-moz-border-radius-topleft: 4px;
	-moz-border-radius-topright: 4px;
	-moz-border-radius-bottomright: 0px;
	-moz-border-radius-bottomleft: 0px;
	border-top-left-radius:4px;
	border-top-right-radius: 4px;
	border-bottom-right-radius: 0px;
	border-bottom-left-radius: 0px; 
	background: #C9C9C9; /* old browsers */
	background: -moz-linear-gradient(top, #0C91EC 0%, #257AB6 100%); /* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0C91EC), color-stop(100%,#257AB6)); /* webkit */
}

.one > .tabs > ul > li:hover{
	background: #FFFFFF; /* old browsers */
	background: -moz-linear-gradient(top, #FFFFFF 0%, #F3F3F3 10%, #F3F3F3 50%, #FFFFFF 100%); /* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(10%,#F3F3F3), color-stop(50%,#F3F3F3), color-stop(100%,#FFFFFF)); /* webkit */
	cursor:pointer;
	color: #333;
}

.one > .tabs > ul > li.tabActiveHeader{
	background: #FFFFFF; /* old browsers */
	background: -moz-linear-gradient(top, #FFFFFF 0%, #F3F3F3 10%, #F3F3F3 50%, #FFFFFF 100%); /* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(10%,#F3F3F3), color-stop(50%,#F3F3F3), color-stop(100%,#FFFFFF)); /* webkit */
	cursor:pointer;
	color: #333;
}

.one > .tabscontent {
	-moz-border-radius-topleft: 0px;
	-moz-border-radius-topright: 4px;
	-moz-border-radius-bottomright: 4px;
	-moz-border-radius-bottomleft: 4px;
	border-top-left-radius: 0px;
	border-top-right-radius: 4px;
	border-bottom-right-radius: 4px;
	border-bottom-left-radius: 4px; 
	padding:10px 10px 25px;
	background: #FFFFFF; /* old browsers */
	background: -moz-linear-gradient(top, #FFFFFF 0%, #FFFFFF 90%, #e4e9ed 100%); /* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(90%,#FFFFFF), color-stop(100%,#e4e9ed)); /* webkit */
	margin:0;
	color:#333;
}


/*Style Two*/

.two {
	width:700px;
	padding:15px;
	background-color:#f3f3f3;
	-moz-border-radius: 4px;
	border-radius: 4px; 
}

.two > .tabs{
	height:30px;
}

.two > .tabs > ul{
	font: 1em;
	list-style:none;
}

.two > .tabs > ul > li{
	margin:0 2px 0 0;
	padding:7px 10px;
	display:block;
	float:left;
	color:#333;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-o-user-select: none;
	user-select: none;
	-moz-border-radius-topleft: 4px;
	-moz-border-radius-topright: 4px;
	-moz-border-radius-bottomright: 0px;
	-moz-border-radius-bottomleft: 0px;
	border-top-left-radius:4px;
	border-top-right-radius: 4px;
	border-bottom-right-radius: 0px;
	border-bottom-left-radius: 0px; 
	background: #fff; 
	cursor:pointer;
}

.two > .tabs > ul > li:hover{
	background: #666; 
	cursor:pointer;
	color: #fff;
}

.two > .tabs > ul > li.tabActiveHeader{
	background: #666;
	cursor:pointer;
	color: #fff;
}

.two > .tabscontent {
	-moz-border-radius-topleft: 0px;
	-moz-border-radius-topright: 6px;
	-moz-border-radius-bottomright: 6px;
	-moz-border-radius-bottomleft: 6px;
	border-top-left-radius: 0px;
	border-top-right-radius: 6px;
	border-bottom-right-radius: 6px;
	border-bottom-left-radius: 6px; 
	padding:10px 10px 25px;
	background: #666; 
	margin:0;
	color:#FFF;
}

/*Style Three*/

.three {
	width:700px;
	padding:15px;
	background-color:#ffffff;
	-moz-border-radius: 4px;
	border-radius: 4px; 
}

.three > .tabs{
	height:31px;
}

.three > .tabs > ul{
	font: 1em;
	list-style:none;
	width:195px;
	float:right;
}

.three > .tabs > ul > li{
	margin:0 0 0 2px;
	padding:7px 10px;
	display:block;
	float:left;
	color:#333;
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
	background: #B6C9DB; /* Old browsers */
	background: -moz-linear-gradient(top, #B6C9DB 0%, #A0B1BF 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#B6C9DB), color-stop(100%,#A0B1BF)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top, #B6C9DB 0%,#A0B1BF 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top, #B6C9DB 0%,#A0B1BF 100%); /* Opera11.10+ */
	background: -ms-linear-gradient(top, #B6C9DB 0%,#A0B1BF 100%); /* IE10+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#B6C9DB', endColorstr='#A0B1BF',GradientType=0 ); /* IE6-9 */
	background: linear-gradient(top, #B6C9DB 0%,#A0B1BF 100%); /* W3C */
	border-top:1px solid #999;
	border-right:1px solid #999;
	border-left:1px solid #999;
	border-bottom:1px solid #999;
}

.three > .tabs > ul > li:hover{
	background: #FFFFFF; /* Old browsers */
	background: -moz-linear-gradient(top, #FFFFFF 0%, #FFFFFF 10%, #E4E9ED 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(10%,#FFFFFF), color-stop(100%,#E4E9ED)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* Opera11.10+ */
	background: -ms-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* IE10+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#E4E9ED',GradientType=0 ); /* IE6-9 */
	background: linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* W3C */
	border-bottom:1px solid #e4e9ed;
	cursor:pointer;
	color: #333;
}

.three > .tabs > ul > li.tabActiveHeader{
	background: #FFFFFF; /* Old browsers */
	background: -moz-linear-gradient(top, #FFFFFF 0%, #FFFFFF 10%, #E4E9ED 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(10%,#FFFFFF), color-stop(100%,#E4E9ED)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* Opera11.10+ */
	background: -ms-linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* IE10+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#E4E9ED',GradientType=0 ); /* IE6-9 */
	background: linear-gradient(top, #FFFFFF 0%,#FFFFFF 10%,#E4E9ED 100%); /* W3C */
	border-bottom:1px solid #e4e9ed;
	cursor:pointer;
	color: #333;
}

.three > .tabscontent {
	padding:10px 10px 25px;
	background: #E4E9ED; /* Old browsers */
	background: -moz-linear-gradient(top, #E4E9ED 0%, #FFFFFF 10%, #FFFFFF 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#E4E9ED), color-stop(10%,#FFFFFF), color-stop(100%,#FFFFFF)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top, #E4E9ED 0%,#FFFFFF 10%,#FFFFFF 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top, #E4E9ED 0%,#FFFFFF 10%,#FFFFFF 100%); /* Opera11.10+ */
	background: -ms-linear-gradient(top, #E4E9ED 0%,#FFFFFF 10%,#FFFFFF 100%); /* IE10+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E4E9ED', endColorstr='#FFFFFF',GradientType=0 ); /* IE6-9 */
	background: linear-gradient(top, #E4E9ED 0%,#FFFFFF 10%,#FFFFFF 100%); /* W3C */
	border:1px solid #999;
	margin:0;
	color:#333;
}

So our CSS uses lots of gradients and border radius and other CSS3 beautification as before. What you will notice is I have created three sets of styles all slightly different and the only differentiation on the selectors is the prefix of either “one”, “two” or “three”. (I could have added more but for this it is fine).
The reason I have done this, is so we can send a parameter to the plugin to choose which styling we would like.

The Plugin

(function($){  
        $.fn.acidTabs = function(options) {
               //Plugin Code Goes Here
          };
    })(jQuery);

So first of all we set up an anonymous function (closure) to stop any conflicts with other library namespaces. Then we add a new function property to the jQuery.fn object where the name of the property is the name of my plugin i.e. acidTabs (I’m already regretting the name).

(function($){  
        $.fn.acidTabs = function(options) {
               var settings = {
      				'style' : 'one'
   				};     
		options = $.extend(settings, options);
          };
    })(jQuery);

Because we want to add a parameter (to change the styling of the tabbed navigation) we create an object within the function called settings and give it one property which is style and give it a default value of “one”, we then extend the options parameters to include the setting object.

(function($){  
        $.fn.acidTabs = function(options) {
               var settings = {
      				'style' : 'one'
   				};     
		options = $.extend(settings, options);
                return this.each (function () {		
			var o = options;
			var container = this;
			container.setAttribute("class",o.style);
		});
         };
    })(jQuery);

Next to maintain the chainability of the plugin have to return this. (I am not sure that my plugin needs to maintain chainability but it is best practice to do so.) I also set two variables here one that holds the options that we created earlier (from the parameters) and the second hold the this object (which in this case is the div that we set the acid tabs on). Then I set a class on the outer container div with the value of o.style which will be the css style that we put as a parameter when setting acidTabs. If you don’t set one it will default to “one”.

(function($){  
        $.fn.acidTabs = function(options) { 	
		var settings = {
      			'style' : 'one'
   	         };     
		options = $.extend( settings, options );
		return this.each (function () {		
			var o = options;
			container = this;
			container.setAttribute("class",o.style);
			var navitem = container.querySelector("li");
			//store which tab we are on
			var ident = navitem.id.split("_")[1];
			navitem.parentNode.setAttribute("data-current",ident);
			//set current tab with class of activetabheader
			navitem.setAttribute("class","tabActiveHeader");
				
			//hide two tab contents we don't need
			var pages = container.querySelectorAll(".tabpage");
			for (var i = 1; i < pages.length; i++) {
				pages[i].style.display="none";
			}
				
			//this adds click event to tabs
			var tabs = container.querySelectorAll("li");
			for (var i = 0; i < tabs.length; i++) {
				tabs[i].onclick=displayPage;
			}
		});
					
		// on click of one of tabs
		function displayPage() {
		  var current = this.parentNode.getAttribute("data-current");
		  //remove class of activetabheader and hide old contents
		document.getElementById("tabHeader_" + current).removeAttribute("class");
		document.getElementById("tabpage_" + current).style.display="none";
						
		var ident = this.id.split("_")[1];
		//add class of activetabheader to new active tab and show contents
		this.setAttribute("class","tabActiveHeader");
		document.getElementById("tabpage_" + ident).style.display="block";
		this.parentNode.setAttribute("data-current",ident);
		}
	};
    })(jQuery);

So this is the code for the full plugin as you can see the rest of the code is the same as what we used in the previous post, nothing has really changed yet we have made this code into a jQuery plugin. Pretty easy eh?
Now all we need to do is call the plugin.



At the bottom of our page after we have brought in the jQuery Library and our plugin script we just use the jQuery document ready function and the pass in the id of our outer container to our plugin. See how it looks here.
View Demo 1
If we want to change the styling to style two we just put:

$("#tabContainer").acidTabs({
     style: "two"											 
	});

You can even add more styles just by updating the CSS file.
Thats all for now.
Cheers

View Demo 1View Demo 2Download Source

6 thoughts on “jQuery Tabs Plugin | My first jQuery Plugin

  1. Pingback: Selecting a specific tab on page load with the jQuery plugin "Acid Tabs" - feed99

  2. Daniel Gradwell

    Hi Matt, this is an excellent example but I am trying to get the tabs to work within a table structure where the tables already have classes assigned again them. It just does not want to work.

    This is an extract of the code

    Page 1
    Page 2
    Page 3

    Page 1

    …….

    Any chance you could give me an point in the right direction.

    Thanks

    Reply
  3. Pingback: 20+ jQuery tab plugins for your next website - JqueryMag

  4. Charlie Figura

    Hi! I love your tab setup, and have implemented it on my weather page. I’m wondering if there’s a way to encode specific tabs on the web address, and remember which tab a window was set on during a refresh?

    Thanks!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *