Hey Blogies,
Tabs has became a huge trend in Web Browsers, I dont think there is a web browser out there that does not have tabs. Well not any new browsers. Pretty much everyones tabs are the same rounded corners on the top and two in rounded corners on the botom. Safari is a little different just flipping that scheme.



Then there is Google Chrome. Chrome has the most unique looking tabs. Their tabs mock tabs on minilla files. This is one of the reasons I fell in love with Chrome is because the different approach to their tab UI. I have been using CSS3 for a while now and wondered, is it possible to make Chrome tabs in pure CSS? and like most of the time with CSS3 the answer is YES.
![]()
Now with this build I separated the css into two parts. First the basic structure of the tabs. Meaning the shape and layout. The second half is theming. It is one of the cool features that chrome has, themes. So I decided to separate the parts so that you can look at all the coloring for the themes, and create your own.
Compatability
Ok before we get started, this works on Chrome 13, Firefox 6. Opera 11, and Safari 5. Other versions have not beens tested, and W3C Standards are used for border-radius, and box-shadow. Gradients have been generated at Ultimate CSS3 Gradient Generator.
IE 9 Probably will not render this too well.
Structure - HTML
Ok, First we going to need to construct a list, Im going to use a unordered list with list-items, and anchor tags for the links.
<div class="wrap">
<ul class="tab-list">
<li class="current">
<a href="#page-1">Page 1</a>
</li>
<li>
<a href="page-2">Page 2</a>
</li>
<li>
<a href="#page-3">Page 3</a>
</li>
<li>
<a href="#page-4">Page 4</a>
</li>
</ul>
<!-- Added in two other elements -->
<div class="clearfix"></div>
<div class="bar"></div>
</div>
As you can notice I added a clearfix to clear the floats, we will be adding, and also added a bar so that we can have a small bar underneath to complete that tab look. Oh and we wrapped it all up so we can handle the width for both with one container.
Modifying Structure to handle advanced Shapes - HTML
The Structure we set is up is a solid navigation bar. It is a basic structure and we need to add some elements so that the tabs have the feel as what were trying to emulate. Mainly for the bottom inner corners. You can see a tutorial how to do this here.
<li class="current">
<a href="#page-1">Page 1</a>
<div class="left-mask">
<span></span>
</div>
<div class="right-mask">
<span></span>
</div>
</li>
As you can see we need two elements for each corner. A div to mask our corner and a modified span to create the shape. The outside div will use a technique called masking. Masking is were I will give the Div a overflow hidden so that it will hide parts of the child element.
Two Reasons - The shape will not fit in that area without it, and this will maximize our hit area for the link in the tab.
Im going to add the modified structure to one list item. the one with the current class. So we can hash out the shape without overloading our layout.
Tips – We can statically add this extra content later, or we can add it dynamically, with javascript, like in the demo.
Ok now to the goods!
Basic Construct – CSS
Note if you following along. Some of the changes will be hard to see so you might want to add some extra non-obtrusive styling. I like box-shadow with an inset for this.
/* Tab Structure */
.tab-list{
list-style-type: none;
overflow: hidden;
height: 35px;
margin: 0;
padding: 0;
}
.tab-list li{
margin-top: 10px;
height: 60px;
width: 225px;
position: relative;
float:left;
border-top-right-radius: 20px 60px;
border-top-left-radius: 20px 60px;
border: 1px solid transparent;
margin-left: -25px;
z-index: 1;
}
.tab-list li:first-child{
margin-left: 0;
}
.tab-list .current{
z-index: 2;
}
.left-mask, .right-mask{
width: 10px;
height: 3px;
overflow: hidden;
position: absolute;
top: 20px;
}
.current .left-mask, .current .right-mask{
height: 4px;
}
.left-mask{
left: -1px;
}
.right-mask{
right: -1px;
}
.left-mask span, .right-mask span{
display: block;
width: 9px;
height: 9px;
border-width: 5px;
border-style: solid;
border-color: #fff;
border-radius: 10px;
}
.left-mask span{
margin: -10px -9px;
}
.right-mask span{
margin: -10px 0px;
}
.tab-list li a{
display: block;
float: left;
line-height: 25px;
padding-left: 40px;
font-family: sans-serif;
font-size: 13px;
background-image: url(default.png);
background-repeat: no-repeat;
background-position: 18px center;
color: #444;
text-decoration: none;
}
/* Wrap Centered*/
.wrap{
padding: 0;
margin: 0 auto;
width: 960px;
overflow: hidden;
}
/* Clear Fix took for HTML 5 Boilerlate*/
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }
Masking
Like mentioned before we are going to be working with mask. The masked for the corners are labeled as `.right-mask`, and `.left-mask`. You can see that they have the style `overflow: none;`. Another mask is the actually the unordered list. This is because to get the shape required the list items have to be allot taller then what is shown on the page. This is due to the second parameter in `border-radius`.
Border Radius
On the list item we add a pretty crazy `border-radius`. It is `20px 60px` meaning the top radius are set to 20px, while the left and right are set to `60px`. if the divs height was less the `60px`, the border radius would fix its self to that height, hence the masking. This gives the look of slightly rounded at the top and dropping drastically on the sides. This is what it would look like without the mask.
So now inside of the mask we use a technique that can be found here. It Essentially makes an inside corner. What we use he is a lil more advanced just due to the mask.
Positioning
Everything is positioned pretty basically. Except the two corners which are positioned absolutely to the parent li. The parent is relative and the corner divs are absolute. One last thing before we get to the theme, notice I give a `z-index` of 1 to each list item. except on the current li i give a 2. To make it layer over the other list-items.
Themeing – CSS
The theme portion is pretty simple if you use a gradient generator. Here is the one I used. It is amazing.
/*
Theme For Tabs - based off of Chrome Default on MacOS X
Gradients Generated by: http://www.colorzilla.com/gradient-editor/
*/
.tab-list{
box-shadow: inset 0 1px 1px #fff, inset 0 -1px 1px #9c9c9c;
background: rgb(207,207,207); /* Old browsers */
background: -moz-linear-gradient(top, rgba(207,207,207,1) 0%, rgba(176,176,176,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(207,207,207,1)), color-stop(100%,rgba(176,176,176,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(207,207,207,1) 0%,rgba(176,176,176,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(207,207,207,1) 0%,rgba(176,176,176,1) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(207,207,207,1) 0%,rgba(176,176,176,1) 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cfcfcf', endColorstr='#b0b0b0',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(207,207,207,1) 0%,rgba(176,176,176,1) 100%); /* W3C */
}
.tab-list li{
background: rgb(255,255,255); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(220,221,220,1) 4%, rgba(207,208,207,1) 39%, rgba(156,156,156,1) 40%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(4%,rgba(220,221,220,1)), color-stop(39%,rgba(207,208,207,1)), color-stop(40%,rgba(156,156,156,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(220,221,220,1) 4%,rgba(207,208,207,1) 39%,rgba(156,156,156,1) 40%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(220,221,220,1) 4%,rgba(207,208,207,1) 39%,rgba(156,156,156,1) 40%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(220,221,220,1) 4%,rgba(207,208,207,1) 39%,rgba(156,156,156,1) 40%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#9c9c9c',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(255,255,255,1) 0%,rgba(220,221,220,1) 4%,rgba(207,208,207,1) 39%,rgba(156,156,156,1) 40%); /* W3C */
border: 1px solid #9c9c9c;
box-shadow: inset 0 0 2px #fff;
}
.tab-list li.current{
background: rgb(255,255,255); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(231,231,231,1) 30%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(30%,rgba(231,231,231,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(231,231,231,1) 30%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(231,231,231,1) 30%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(231,231,231,1) 30%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e7e7e7',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(255,255,255,1) 0%,rgba(231,231,231,1) 30%); /* W3C */
}
.left-mask span, .right-mask span{
border-color: rgba(207,208,207,1);
}
.left-mask span{
box-shadow: inset -1px 0 1px #9c9c9c;
}
.right-mask span{
box-shadow: inset 1px 0 1px #9c9c9c;
}
.current .left-mask span, .current .right-mask span{
border-color: rgba(231,231,231,1);
}
.bar{
background: rgb(231,231,231); /* Old browsers */
background: -moz-linear-gradient(top, rgba(231,231,231,1) 0%, rgba(210,210,210,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(231,231,231,1)), color-stop(100%,rgba(210,210,210,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(231,231,231,1) 0%,rgba(210,210,210,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(231,231,231,1) 0%,rgba(210,210,210,1) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(231,231,231,1) 0%,rgba(210,210,210,1) 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e7e7e7', endColorstr='#d2d2d2',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(231,231,231,1) 0%,rgba(210,210,210,1) 100%); /* W3C */
border-bottom: 1px solid #9c9c9c;
}
Most of the gradients are self explanatory, except the one on the tabs. The only reason is that most of the tabs is covered by the mask, Around 60% of it. Thats why the tab gradients start around 40% rather then at 100%. On the greater above this is easily achievable. Also on the in-active tabs the bottom of the gradient also creates the top border for the bar. So Watch out for that. Box shadow is used quite a bit for highlights and on the inner corner thats what gives the illusion of a connecting border.
If you still here, heres how you add the elements dynamically to the page. Because WordPress does not do this by default. LOL
Javascript
Im going to be pretty brief with explaining the javascript / jQuery because ill just comment it in the code. Add jQuery to your page, if you are doing it to a WordPress page or a pre built theme. Chance are its already on there.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
Next a some fun with jQuery
//Auto Initiating Function
(function ($) {
// Select Tab List
$('.tab-list')
// Find the List Item .. makes an Array
.find('li')
// Loops So Each Item gets Assets
.each(function () {
// Assests for tab look
var template = '<div class="left-mask">\
<span></span>\
</div>\
<div class="right-mask">\
<span></span>\
</div>';
//Append Asset / Template to each List Item
$(this)
.append(template);
});
} (jQuery));
So have fun with these styles as you can see I did with the demo. Any Questions? Leave them in the comment section below, and make sure to share ^.^
Update September 2 2011
So I have found out that the structure is rendered pretty well on IE 9, but the theme is not. The only issue is with the gradients. Apparently IE does not want to cut off gradients in a rounded cornered element. This causes the overflow to askew the look of the tabs. Ill post version without gradients in IE in a couple days.Also the Chrome tabs look pretty good in Android browsers as well. There seems to be a lack of support for box shadow inset but the feel is still there. If you have an iPhone let me know how it looks in your browser.


February 14, 2012 at 3:49 am
Wow, Great work… I tried to create similar tabs prior to doing this, you’re blew mine out of the water XD
June 5, 2012 at 4:13 pm
Great work! These look and work great in the web app my team and I are creating.
Unfortunately our client just informed us they will be using IE9, maybe even lower.
Although the only problem I’m having is the gradient to be applied to each inactive tab in IE9, I really hope we can convince them to use chrome instead.
Thank you very much!
June 5, 2012 at 4:45 pm
I would make a fallback to use images for those browsers instead. You might want to talk about added security benefits in Chrome, or just build a simple Google Chrome extension that improve the functionality of the webapp so they want to use Chrome.
For the gradient issue there is some pretty good solutions here
http://stackoverflow.com/questions/4692686/ie9-border-radius-and-background-gradient-bleeding