From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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:
- Responsive Content Navigator with CSS3
- Accordion with CSS3
- Page Transitions with CSS3
- Sliding Image Panels with CSS3
- Animated Web Banners With CSS3
- Filter Functionality with CSS3
- Fullscreen Background Image Slideshow with CSS3
- CSS3 Lightbox
- Splash and Coming Soon Page Effects with CSS3
- Original Hover Effects with CSS3
- Animated Buttons with CSS3
- Creative CSS3 Animation Menus
- Blur Menu with CSS3 Transitions
Wow~~I like it!!
Very nice work 😉
Useful & awesome!
thank’s , very nice work 🙂
wow… :). Thanks for sharing……
Great work guys! Like always.
muito bom, gostei!
Thanks for sharing. Really nice, congratulations.
nice !
Good work !, very util !
Excellent!
Very nice!
Very usefull 🙂 Thanks 😉
demo3 – amazing!!!
Wow, amazing. Love it!
Thanks for sharing this.
What are the advantages of these Tabs versus the Spry Tabs that DreamWeaver uses?
Nice but how to make it compatible with IE6,IE7&IE8?
Thanks for the tutorial! 🙂
1/cosC results. Another fabulous tut.
This is really great. Thanks for sharing!
all is good \m/
Very cool! I just love these tabbed concepts I am seeing. Remember Google still views all of this content as one page, so don’t cram your whole site on this, but its such a cool way of breaking up pages that otherwise would be wordy. So if used right this can be a really great SEO tool, and it vastly improves the user experience!
Hey I also made same tabs using the same technique but just with fade in out effect, here is the link for it http://webstutorial.com/css3-tabs/css3 I hope everyone likes it, and suggestions are welcome 🙂
The 3rd demo is great. Awsome tutorial!
Very nice I like it.. good job 😀
Hi Ring
Interesting tutorial, there are many jquery tab tutorials around but I haven’t seen many with the transition effects shown here. My personal favourite is demo number two, I think the sliding effect is quite unique. Number 3 is also nice, however I think the sliding effect used in number four is a bit too much.
Cathy
Your tutorials have been a life saver to me and me recent endeavors! Thank you!
beautiful
@John – These are just experiments to show what we can do with CSS3, but if you want to use them in production sites then you will have to create fallback solutions for crappy IE. I believe that’s the way we have to work right now and still have to for a long, long time. All thanks to the ridiculous IE new release cycle of Microsoft. If we have to wait for the time that we can stop supporting IE8 or even IE9 (which has also poor CSS3 support) so that we ‘can’ start using CSS3, then we’re probably 10 years further. I’m not going to wait for that… Are you?
Nice tutorial and clever technique. But this is wrong use of radio. I prefer uses links (with #) as tabs.
Hi,
i’ve tried to use this table but i can’t use html code inside the tabs. Why?
I try to do a contact tab with input inside but the tab don’t show anything.
Hi Alex, when you connect the ‘label’ to the ‘input’, make sure that you set the same value for ‘id’ and ‘for’ attribute. Here is the message from W3C: adjacent sibling combinator, general sibling combinator
sorry but it don’t works.
However, I try to include a very very simple div in the tab,too, (for another function that i need) but
if i wrote
doesn’t appeare nothing
I’m having the same issue. I believe the div is being hidden behind the tab, but setting a z-index doesn’t seem to change anything. =/
I don’t know exactly what you mean, but the code has no problem. Make sure that you understand the sibling combinator. If you don’t like the z-index, you can use visibility. Just use you mind!
me too. when I try to make another div within content-1 div, nothing inside the div i made appears. i’ll try visibility.
basically what Alex means is that content within another div cannot be added to each tab’s content area or ‘content-1’ divs because it doesn’t show which what i’m trying to figure out too.
there is conflicting code that does not allow the showing of other divs inserted into the ‘content-x’ divs. could it have something to do with being hidden due to z-indexing? i’m not too experienced with css3 so my mind is fried now lol
Hi Ring,
really awesome tutorial, I wold like to know, if possible, how I can make the same tabs with a variable height.
Thanks so much! =)
Hi Andrea, take this demo for example, you can add the
background
and thepadding
to each of tab pages, not the class content, and give the content of tab pages some transitions if you need it.having same problem–can’t put divs into content-1 div because it won’t show :(. not too familiar with css3. any help would be appreciated.
Hi, the code just for the demo, you should act according to circumstances! I’ve used the descendant combinator for the divisions, you can use the child combinator or add the unordered list.
There is an end to a problem like this. Just use you mind!
hi Ring,
the problem is that if i insert in a tab a very long text\code it don’t show everything.How can i make a tab with dynamic height?
I have told you already, set the height of the class content and tab pages to auto, and give each of tabs a background. Take note of the overflow. It’s done.
No ajax, no jquery? Excellent 🙂
great tutorial. Any way to adjust the heights of each content box? Thanks
You have on the final of the style.css several kind of heights:
.ac-container input:checked ~ article.ac-1{
height: 455px;
}
.ac-container input:checked ~ article.ac-2{
height: 370px;
}
Change them…
Sorry, in this case:
.ac-container input:checked ~ article.ac-medium{
height: 455px;
}
.ac-container input:checked ~ article.ac-large{
height: 370px;
}
….
It’s beautiful! thanks! but please, how can I make it compatible with IE6-IE7&IE8? some tutorial? I need to make this tabs compatible with IE urgent 🙁
Wow! All your works are just so amazing! THANK YOU! You’ve helped me so much!
Hey,
very awesum stuff!
I implement it in one website already. Now i want to pimp up my WordPresstheme with you Tabs!
Under each article i want to activate these tabs. In the tabs you will finde the Comments or the Gallery.
But if I set the Tabs two times on one .html File. I wont work corectly. Pleas try out!
Do you have a solution to fix it?
Please contact me and i’ll sent a code example.
Best regards,
Roberto
Great, thank you but how do you put html content within the tabs, as soon as i put divs inside, the content disapears?
Hi, if you use an tag or a tag it works 🙂 Use them instead of divs to display your content 🙂
Opps! used the around my words so they dissappeared 😛
What I met to write is that if you use an article tag or a section tag instead of divs your content wont dissappear 🙂
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
Among other things, I changed this in the CSS:
.tabs5 label { width: 20%; }
Every content and label tag needs to be unique.
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 :))
Why i can’t use form tag with this.I tried but It didn’t show any textbox or submit button.please help
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
Internet Explorer sucks!! i could not use it in IE
thanks for this great tutorial. i am using its customize version in my project
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
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.
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.
Forget about it, fixed it 😀
Great !.
Tnkx for sharing !
Daniel.
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