J.me

Simple jQuery and CSS3 Slideshow Tabs

A slideshow and tabs is pretty common nowadays in any modern website. There is a ton of way to do this and many free and paid tools available for this feature. This make it very easy to create and it will always amaze people who see it. Basically, we will need at least Javascript to do this, CSS to style the slideshow and tabs as we wanted, and then finally the special HTML markup which make it possible. There is also a slideshow which make use of Flash.

The solution I tried to made right now is a very simple and basic one. It make use of simple jQuery to catch the click event and switching tabs, as well as the slideshow, the CSS to style it as much as we wanted and a simple HTML markup in one unordered list.

The Markup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<ul class="tabs tabs-1"> 
	<li> 
		<a class="tab-select" href="#tab1">1</a> 
		<div class="tab-content" id="tab1"> 
			<img src="tab-images/tab1.jpg" alt="Tab 1" /> 
		</div> 
	</li> 
	<li> 
		<a class="tab-select" href="#tab2">2</a> 
		<div class="tab-content" id="tab2"> 
			<img src="tab-images/tab2.jpg" alt="Tab 2" /> 
		</div> 
	</li> 
	<li> 
		<a class="tab-select" href="#tab3">3</a> 
		<div class="tab-content" id="tab3"> 
			<img src="tab-images/tab3.jpg" alt="Tab 3" /> 
		</div> 
	</li> 
	<li> 
		<a class="tab-select" href="#tab4">4</a> 
		<div class="tab-content" id="tab4"> 
			<img src="tab-images/tab4.jpg" alt="Tab 4" /> 
		</div> 
	</li> 
</ul>

The markups is as simple as it can get. It consists of an un-ordered list, with each list containing one anchor for navigation and one div for content.

The Javascripts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
<script type="text/javascript"> 
	jQuery(document).ready(function($){
		$('.tabs').each(function(){
			$(this).find('li:first').addClass('current'); // set the first tab to display
			repeat_slideshow($(this));
		});
		$('.tabs li .tab-select').click(function(){
			$(this).closest('.tabs').find('li').not($(this).parent()).removeClass('current'); // hide all tabs except for the current
			$(this).parent().addClass('current'); // set the current tab to display
			reset_slideshow($(this).closest('.tabs'));
			return false;
		});
		function slideshow(slide)
		{
			var index = slide.find('li.current').index();
			var total = slide.find('li').length;
			if ( index+1 >= total )
				var next = 0;
			else
				var next = index + 1;
			slide.find('li.current').removeClass('current');
			slide.find('li').eq(next).addClass('current');
		}
		function repeat_slideshow(slide)
		{
			slide.data('slideshow', setTimeout(function(){
					slideshow(slide);
					repeat_slideshow(slide);
				}, 5000));
		}
		function stop_slideshow(slide)
		{
			clearTimeout(slide.data('slideshow'));
		}
		function reset_slideshow(slide)
		{
			stop_slideshow(slide);
			repeat_slideshow(slide);
		}
	});
	</script>

This code is pretty much simple, it only toggles tab by changing class properties. It relies to the CSS to deliver the actual tabs toggling.

The CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<style type="text/css"> 
	.tabs
	{
		position: relative;
		height: 430px;
		width: 640px;
		list-style-type: none;
		margin: 10px 0 40px;
		padding: 0;
		overflow: hidden;
	}
	.tabs-1
	{
		width: 380px;
		padding: 0 0 0 260px;
	}
	.tabs li
	{
		float: left;
	}
	.tabs li .tab-select
	{
		display: block;
		float: left;
		margin: 0 5px 0 0;
		padding: 0 10px;
		background: #e6e6e6;
		color: #666;
		text-decoration: none;
		cursor: pointer;
	}
	.tabs-1 li .tab-select
	{
		height: 20px;
		line-height: 20px;
		-moz-border-radius: 10px;
		border-radius: 10px;
		font-size: 10px;
	}
	.tabs li .tab-content
	{
		position: absolute;
		top: 30px;
		left: 0;
		height: 400px;
		width: 640px;
		opacity: 0;
		-moz-transition: opacity 0.5s linear;
		-o-transition: opacity 0.5s linear;
		-webkit-transition: opacity 0.5s linear;
		transition: opacity 0.5s linear;
		z-index: 2;
	}
	.tabs li .tab-select:hover
	{
		background: #ccc;
		color: #666;
	}
	.tabs li.current .tab-select
	{
		background: #666;
		color: #fff;
		text-shadow: 1px 1px #000;
	}
	.tabs li.current .tab-content
	{
		opacity: 1;
		z-index: 4;
	}
</style>

The CSS define how the tabs will looks. It is mainly used the position properties to maintain the position of the tab content and leave the navigation to static position (either floated or none). Notice the tabs-1 class? That is to demonstrate that even with this approach, we can customize the tab to different looks with exactly same markup structure.

To further explain how it works, first the main .tabs class is considered the area which the content will be placed, we set the position to relative and make sure it had enough height to accomodate the content. Then each list is floated to left, as well as the .tab-select anchor for navigation (in later example, we can also use div).

The content part of each list is set to absolute position. That means, they will overlap each other and make them in always same position. We then used opacity to hide and displaying the content with addition of the CSS3 transform to provide fading animation. Finally, we bring the selected content to the front by applying a bigger z-index value.

Note that, for fading animation, we used the opacity property. If you wanted to use another animation, you need to change it. For no animation, just use display: none and display: block.

Why this approach?

What make this approach better than any others tabs and slideshow?

Well, it might not better. It just that, it is simple and clean enough, at least for me.

Only one unordered list markup needed

Often, I find that a tab are made from two group of lists (when I said lists it can be a group of div, li, or anything). One is for the tab navigation and the other is for the content. Nothing is wrong either way, but I find it easier to create if it is only made on one list. This also apply when we create the markup on the fly using server script such as PHP. If we have two group of lists, this means we need to loop the variable twice, while using one list will only need one loop.

Using one list will also make the HTML cleaner and for those who browsing with text browser, it will degrade gracefully.

Lighter, no Javascript effect

I don’t know if this will be considered a good thing or not, but I don’t use any animation using Javascript nor jQuery effect. 🙂 Instead, I rely on CSS 3 transition for the fade in effect. This, obviously, is not yet a good practice. It is safe to use CSS 3 feature right now, but the lack of browser support make it not yet practical. By far, only new Webkit browser (Safari and Chrome), Opera 10.6+ and Firefox 4 support CSS transition.

Again, why CSS 3? Well, we know that the animation and transition in CSS 3 is not yet matured and experimental for now. It even lagged when we are doing some heavy animation. But when it is matured enough and become a standard, it will be better than any Javascript animation as it will build natively to the browser.

Support multiple slideshow tabs

Well, it make use of two jQuery features that was there but seems to rarely used. They are jQuery.index and jQuery.data. We used jQuery.index to see the current index from the list group to find the next tab to slide. It is more simple than storing a variable and keep it updated when the slide change. Then, the jQuery.data is used to store the setTimeout variable. Why using a jQuery.data and not a variable? jQuery.data allow us to attach data to a DOM element, this way, we can attach each setTimeout variable to the parent group and make it separated to any other slideshow in the same page. So, it support multiple slideshow in the same page without interrupting each other in just a few lines of code. Nice!

The Downside

After all this goodness, obviously, there is still a downside to be considered that it might not suit your need. First of all, the content height is fixed. This is because the use of absolute position for the content. Second, well, the lack CSS3 support on some web browser.

The Demo

Finally, a demo to show you how it actually works.

Check out the demo here.

There is three styles of the slideshow tabs in the demo, so you can see that it is possible to style it in many way to suit your design.

The code is released under GNU General Public License. So feel free to use and modify it in any way you need.

Browser support?

Well, not much browser support this yet. It degrade nicely though. If you open it in older browser that didn’t have CSS 3, it still working all fine except the CSS 3 goodies. So we can say that the CSS 3 goodies is an extra for dude who love using updated browser. 😉

How about Internet Explorer 6? Well, it is not working right as far as I can see. But I think there will be a workaround to solve the IE 6 problem though, but I just don’t have a time to spend on this stupid outdated browser.

Final?

Thank you and hope that useful for you. 🙂

6 comments | Leave a comment

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.