Animated Content Tabs with CSS3

In this tutorial we are going to implement some simple CSS3 content tabs using radio buttons together with the :checked pseudo-class and sibling combinators.


CSS3 Content Tabs

View demo Download source

Content tabs are a very common and familiar element in web design, and often their turn out to be pretty useful. So, in this tutorial we are going to implement some simple CSS3 content tabs using radio buttons together with the :checked pseudo-class and sibling combinators.

Note that the CSS3 properties will only work in browsers that support them.

The Markup

We will be using input elements to connect to the division with the class content. The content division includes all of the “tab pages”. For each input element we’ll have a label element. All labels will be styled like tabs.

<section class="tabs">
    <input id="tab-1" type="radio" name="radio-set" class="tab-selector-1" checked="checked" />
	<label for="tab-1" class="tab-label-1">About us</label>
	
	<input id="tab-2" type="radio" name="radio-set" class="tab-selector-2" />
	<label for="tab-2" class="tab-label-2">How we work</label>
	
	<input id="tab-3" type="radio" name="radio-set" class="tab-selector-3" />
	<label for="tab-3" class="tab-label-3">References</label>
	
	<input id="tab-4" type="radio" name="radio-set" class="tab-selector-4" />
	<label for="tab-4" class="tab-label-4">Contact us</label>
            
	<div class="clear-shadow"></div>
				
	<div class="content">
		<div class="content-1">
            <p>Some content</p>
		</div>
		<div class="content-2">
            <p>Some content</p>
		</div>
		<div class="content-3">
            <p>Some content</p>
		</div>
		<div class="content-4">
            <p>Some content</p>
		</div>
	</div>
</section>

Every input element has a value, and we can always make an input selected by default by adding the checked attribute.

The CSS

The first thing we need to do is to define some dimension and hide the inputs by setting their opacity to 0:

tabs {
    position: relative;
	margin: 40px auto;
	width: 750px;
}

.tabs input {
	position: absolute;
	z-index: 1000;
	width: 120px;
	height: 40px;
	left: 0px;
	top: 0px;
	opacity: 0;
	cursor: pointer;
}
.tabs input#tab-2{
	left: 120px;
}
.tabs input#tab-3{
	left: 240px;
}
.tabs input#tab-4{
	left: 360px;
}

The inputs will be covering the labels. It will seem, as if we click on the label, but actually we are clicking on the input. This is a trick that will also work in mobile browsers (in some mobile browsers, simply clicking the label will not focus the associated input).

Next, we will make the labels look like tabs by defining some neat style for them. Note that each of the labels has a different z-index. A box-shadow will add depth and realism to the tabs.

.tabs label {
	background: linear-gradient(top, #5ba4a4 0%,#4e8c8a 100%);
	font-size: 15px;
	line-height: 40px;
	height: 40px;
	position: relative;
	padding: 0 20px;
    float: left;
	display: block;
	width: 80px;
	color: #385c5b;
	letter-spacing: 1px;
	text-transform: uppercase;
	font-weight: bold;
	text-align: center;
	text-shadow: 1px 1px 1px rgba(255,255,255,0.3);
    border-radius: 3px 3px 0 0;
    box-shadow: 2px 0 2px rgba(0,0,0,0.1), -2px 0 2px rgba(0,0,0,0.1);
}

.tabs input:hover + label {
	background: #5ba4a4;
}

.tabs label:first-of-type {
    z-index: 4;
    box-shadow: 2px 0 2px rgba(0,0,0,0.1);
}

.tab-label-2 {
    z-index: 3;
}

.tab-label-3 {
    z-index: 2;
}

.tab-label-4 {
    z-index: 1;
}

Since we don’t want the bottom part of the box-shadow to show, we will cover it by using a :after pseudo-element with no content:

.tabs label:after {
    content: '';
	background: #fff;
	position: absolute;
	bottom: -2px;
	left: 0;
	width: 100%;
	height: 2px;
	display: block;
}

When we click on a tab (label), it will be different in style and color from the others. The important thing is to make sure that the “checked” label will be on top of all of the other layers in the tabs. So, we will give it the highest z-index:

.tabs input:checked + label {
    background: #fff;
	z-index: 6;
}

As mentioned before, the content division will contain all of the tab pages, and we will set its z-index to 5, just to be under the selected label. In this way, the box-shadow of content area will cover all of the other labels.

Inside the content area, there are four divisions and each of them has their own content. By default (when their respective label is not selected/clicked) we want them to be hidden. So, we set the opacity to zero and the z-index to 1. We cannot use the display: none property because it’s not supported in transitions.

.content {
    background: #fff;
	position: relative;
    width: 100%;
	height: 370px;
	z-index: 5;
    box-shadow: 0 -2px 3px -2px rgba(0,0,0,0.2), 0 2px 2px rgba(0,0,0,0.1);
    border-radius: 0 3px 3px 3px;
}

.content div {
    position: absolute;
	top: 0;
	left: 0;
	padding: 10px 40px;
	z-index: 1;
    opacity: 0;
    transition: all linear 0.1s;
}

.content div h2,
.content div h3{
	color: #398080;
}
.content div p {
	font-size: 14px;
	line-height: 22px;
	font-style: italic;
	text-align: left;
	margin: 0;
	color: #777;
	padding-left: 15px;
	font-family: Cambria, Georgia, serif;
	border-left: 8px solid rgba(63,148,148, 0.1);
}

When we want a content to appear (label clicked) we set the opacity to 1 and raise the z-index because we want this content division to be on top of all the others:

.tabs input.tab-selector-1:checked ~ .content .content-1,
.tabs input.tab-selector-2:checked ~ .content .content-2,
.tabs input.tab-selector-3:checked ~ .content .content-3,
.tabs input.tab-selector-4:checked ~ .content .content-4 {
    z-index: 100;
    opacity: 1;
    transition: all ease-out 0.2s 0.1s;
}

In this tutorial we just went through the basic example that will fade in/out the contents. You can find more styles and effects in the demos.

This tutorial is part of the CSS3 series on Codrops. Check out the other experiments:

View demo Download source

Previous:
Next:

Tagged with:

Ring is a front-end development and a UI/UX designer from Beijing, China. He's passionate about the web and loves e-sports.

View all contributions by

Website: http://fiohistory.com/

Related Articles

Feedback 79

Comments are closed.
  1. 1

    Hi! I’m trying to ad a 5th tab to this code on my site, but i can’t get i t to work. Can you tell me how it’s done, please?
    I copied everything tab-raleted an added the nubmer 5, thes switched the nubmers on the .tab-lables so that no 1 had five and so on:
    .tabs label:first-of-type {
    z-index: 5;
    box-shadow: 2px 0 2px rgba(0,0,0,0.1);
    }

    .tab-label-2 {
    z-index: 4;
    }

    .tab-label-3 {
    z-index: 3;
    }

    .tab-label-4 {
    z-index: 2;
    }

    .tab-label-5 {
    z-index: 1;
    }

    and added:
    .tabs input#tab-5{
    left: 480px;
    }

    Tab 1-3 works perfectly, but now when i hover over tab 4 the 5th tab lightens up and if i cklick it i enter tab 5 and can’t get ahold of tab 4. Can you help showing us how to ad more tabs?

    This is how it looks, if you want to see: http://ace.oru.se/~sankah101/sanna/index.php

    • 2

      Among other things, I changed this in the CSS:
      .tabs5 label {
      width: 20%;
      }

      Every content and label tag needs to be unique.

  2. 3

    Impressive!! Just wanna report this is still unsupported on regular android 4 ICS browser BUT supported FULLY on Google Chrome Android on ICS let’s hope Chrome will be default standard on all device to save us the hassle on user point of view :))

  3. 4

    Why i can’t use form tag with this.I tried but It didn’t show any textbox or submit button.please help

  4. 5

    add a dot”.” to define the property of class on

    “tabs {
    position: relative;
    margin: 40px auto;
    width: 750px;
    }”
    on first css div and first line….!

    -Thanks

  5. 7

    thanks for this great tutorial. i am using its customize version in my project

  6. 8

    How do i link to a particular tab? If i want to link directly tot he 3rd tab for example, how do i do that?

    Thanks

    • 9

      Love the tab functionality. I’m trying to figure out how to open the page with a tab checked dependent on the navigation link clicked. Not sure if that made sense, if I click on the link for contact on the navigation bar it might bring up a new page but with tab 2 selected, where as might click the map link on navigation and tab 4 might become visible. Key I guess is changing pages but yet controlling the checked tab on the landing page. Thanks for the help.

  7. 10

    First of all, thank you for this great tutorial, it was really helpful and I loved the output. I’m having trouble trying to execute an action when you press a tab, I can’t make it work, so far I tried with the radio events like onclick, with the href on “a”, with action in form, just can’t make it work. I’m using Symfony2 and my purpose is to call a path when I click on a tab.

    Thanks.

  8. 13

    Amazing work, I really would like to use it but i want to include in one div content a Google map .. but impossible to show it, I everytime have a gray background, perhaps something is wrong with the css (like the position or the opacity). Do you guys know a solution to this problem ?
    Thank you very much

  9. 14

    Hi!!! I wanted to say that your tutorial is great, but I am trying to put more than one tabbed zone in one html, and it is a mess! I repeat the code and rename it in order to separate the two of them with their own styles but it isn´t working. Because when I press in the one that is below the other the contents in the forst one hide. :S I tried everything, please can you help me? How can I manage to separate the functionality between them???

    Here is my code [Link added by Codrops]

  10. 16

    Hey, I love the way this works. I was able to style and modify demos 3 and 4 with extra tabs and dynamic height.

    For dynamic height, I removed the height from .content, and added position:relative and a background color to the .tabs input.tab-selector-1:checked ~ .content .content-1,
    .tabs input.tab-selector-2:checked ~ .content .content-2,
    .tabs input.tab-selector-3:checked ~ .content .content-3,
    .tabs input.tab-selector-4:checked ~ .content .content-4

    As for adding content within a tab, use instead of and style the span like you would the div.

    If you are trying to add/remove tabs, you have to make sure you add or remove all references for the number of tabs you are adding/removing.

    However, I could not get the code to work with IE8, even with selectivizr. I ended up just making a fallback for it.

  11. 19

    Is there a way by which this can work in IE8 and below? Any help will be greatly appreciated.

  12. 23

    I love love love this. The only problem I’ve found with it is that you can’t add another div element inside the content. Such as

    The title goes here

    You can’t do that, for some reason, it wont let you. Anyone know how to fix this problem?

  13. 24

    Hmm is this close to something i want to implement. Similar to the 4th example. Instead of moving all elements off the screen at once.

    It removes top elements first, followed by the below element. When it switches to a new tab it drops the bottom element down first then places down the above elements ontop.

    Pretty much like what you see in a layered cake game.

  14. 26

    Hello, it is possible have two complete content tabs on one page? I have troubles with this. Correctly works only one content tab :(

Comments are closed.