All PostsTutorials

Building widgets and mini applications using jQuery has become a lot easier over the years. Web developers are constantly writing new tutorials and updating open source projects in code repos such as Github or BitBucket. This provides an enormous amount of educational information and has expanded the way we build websites.

In this tutorial I want to demonstrate one such method for creating dynamic content tabs. We will load in external HTML data from local files pulled via Ajax commands. This technique has been simplified over the years so we aren’t struggling to build multiple XMLHttpRequest calls. Check out the demo page below and see what we’ll be creating.

Live Demo PreviewDownload Source Code

HTML Page Structure

I will gloss over the HTML a bit so we can move into the tab styles and scripts. But constructing the page markup is just as important, and we will be doing so using an unordered list combined with a content wrapper.

<!doctype html>
<html lang="en-US">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>jQuery Tabs Widget Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="https://www.bestseocompanies.com/favicon.ico">
  <link rel="icon" href="https://www.bestseocompanies.com/favicon.ico">
  <link rel="stylesheet" type="text/css" href="styles.css">
  <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Wendy+One">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" charset="utf-8" src="scripts.js"></script>
<!--[if lt IE 9]>
  <script type="text/javascript" src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

Looking at the document header I am including some of the typical documents we use in most tutorials. I’ve got a copy of the most recent jQuery library along with a new Google Webfont named Wendy One. The local script.js contains our basic jQuery commands which fire whenever a new tab is clicked.

<div id="w">
    <h1>jQuery Animated Tabs via Ajax</h1>
    <div id="tabs">
      <ul class="links clearfix">
        <li><a href="intro.html" class="noshadow">Intro</a></li>
        <li><a href="about.html" class="active">About Us</a></li>
        <li><a href="photos.html">Photos</a></li>
        <li><a href="videos.html">Videos</a></li>
        <li><a href="links.html">Other Links</a></li>
      </ul>
      
      <div id="content">
        <div id="content-wrap">
          <h2>About the Site</h2>
          ....
        </div>
      </div> <!-- /#content -->
    </div>  <!-- /#tabs -->
</div> <!-- /#w -->

The body content is divided heavily by multiple div containers. The whole widget is wrapped inside a #tabs div which contains two main pieces. The first is an unordered list of tabbed links at the top, followed by a #content div.

Now we could put the HTML directly in here, except when we replace the content for new HTML the div would shrink and lose the white background. By appending all the HTML inside another div labeled #content-container we can safely fade the content without losing all of the white container background.

Stylin’ with CSS

Inside the stylesheet document we can find all the major gradients and transition effects. These may not work as properly(or at all) running in older versions of Internet Explorer. But where JavaScript is allowed we can overwrite the CSS transitions using jQuery as a fallback.

tabs .links { }
#tabs .links li { margin: 0; }
#tabs .links li a {
  font-family: 'Trebuchet MS', Tahoma, Arial, sans-serif;
  color: #4b3854;
  font-size: 1.7em;
  line-height: 50px;
  height: 50px;
  padding: 0 1.5em;
  float: left;
  display: block;
  position: relative;
  font-weight: bold;
  text-shadow: 1px 1px 0px rgba(255,255,255,0.3);
  border-radius: 4px 4px 0 0;
  box-shadow: -2px 0 2px rgba(0,0,0,0.3);
  background: #835ba4;
  background: -moz-linear-gradient(top, #926db5 0%, #6e4e8c 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#926db5), color-stop(100%,#6e4e8c));
  background: -webkit-linear-gradient(top, #926db5 0%,#6e4e8c 100%);
  background: -o-linear-gradient(top, #926db5 0%,#6e4e8c 100%);
  background: -ms-linear-gradient(top, #926db5 0%,#6e4e8c 100%);
  background: linear-gradient(top, #926db5 0%,#6e4e8c 100%);
  -webkit-transition: all linear 0.3s;
  -moz-transition: all linear 0.3s;
  transition: all linear 0.3s;
}
#tabs .links li a:hover { 
  text-decoration: none; 
  left: 10px;
  color: #73448a;
}

I skipped over the default CSS resets because most web developers can put in their own. But if you need a better template for getting started I recommend Eric Meyer’s CSS resets. In the code above I am defining the styles for each list item and the internal link. I have applied many CSS3 properties including a box shadow, text shadow, border radius, and background gradient effect.

You will also notice some transition properties at the bottom of the list. These animations will only perform two tasks – highlighting the tab text color and pushing the hovered tab over to the left. It’s a neat little effect which you wouldn’t have thought was possible using merely CSS properties.

#tabs .links li a.active {
  text-decoration: none;
  left: 0;
  background: #fff;
  color: #603f70;
}

#tabs .links li a.active.noshadow {
  box-shadow: none;
}

#tabs #content { 
  z-index: 9999;
  position: relative;
  top: -1px;
  min-height: 550px;
  background: #fff; 
  padding: 14px 18px;
  padding-top: 20px;
  color: #343434;
  font-family: Arial, Verdana, sans-serif;
  letter-spacing: normal;
  font-size: 1.2em;
  box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2);
}

Whenever a user clicks on a new tab we need to reassign the .active class. This animates the tab’s background color to pure white using a darker text style. We can see this on the default “About Us” tab when the demo first loads. You could theoretically set this default onto any tab in the list, although you will need to manually change the default HTML content since it is not automatically pulled when the page first loads.

Pulling Data with jQuery

The last bit we need to go over is a mere 15-20 lines of code. The script.js file is a continuation of jQuery which is only parsed after the document finishes loading.

We need to bind an event handler onto all of the anchor tab links. Then whenever a user clicks on one, we call a new function with the event variable passed as the parameter. With this method we can stop the default href value from loading by calling e.preventDefault().

#tabs .links li a.active {
  text-decoration: none;
  left: 0;
  background: #fff;
  color: #603f70;
}

#tabs #content { 
  z-index: 9999;
  position: relative;
  top: -1px;
  min-height: 550px;
  background: #fff; 
  padding: 14px 18px;
  padding-top: 20px;
  color: #343434;
  font-family: Arial, Verdana, sans-serif;
  letter-spacing: normal;
  font-size: 1.2em;
  box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2);
}

Each of the anchor links uses an href value related to the remote HTML page which we’re loading. I can setup a string variable pointing directly to this file and then dynamically append the content into our page using .load(). This is one of the easiest resources for pulling quick Ajax content. But note that you will need to host these files on a web server for any Ajax methods to function properly.

The other lines of code are checking against the currently active tab. If we clicked a new tab that wasn’t active before then we need to remove that class off the old tab. Additionally we are pausing before the new content loads to run a set of jQuery .hide() and .fadeIn() methods. These codes provide the fancy transition effects as the content switches along with each tab.

Live Demo PreviewDownload Source Code

Final Thoughts

I hope this tutorial can offer some useful code snippets for various web developers. There are many different reasons you may wish to put together a small tab widget, and there are also many techniques for doing so. This article presents a simplified method which relies on CSS3 animations along with jQuery Ajax calls for loading the new content.

Please download a copy of the project source code and play around on your own. I’m sure this could be helpful to at least a few people, and may provide a handy template for upcoming projects. Additionally if you have any questions or comments feel free to share with us in the post discussion area below.