前几天藤藤在每一练中写了一个《CSS3制作Twitter信息框》效果,酷似Chrome浏览器的tabs效果:
从上面的效果图上来看,似乎有点棘手,特别是tabs底部的内凹圆角之处的处理。当初转这个设计图的时候,我们一起都没有思路,后来在css-tricks中找到了一篇类似于这种设计的教程,仔细阅读后才知道其原理。今天稍有空闲,将其教程Tabs with Round Out Borders介绍的方法转译成中文与大家分享。直接不来,只好转述其文章中的思想精髓,希望对大家有所帮助。
CSS3的border-radius出现,让广大Web前端人员制作圆角不在像以前那样苦逼,直接一个属性就能搞定了。但话说回来,border-radius制作一些普通圆角是方便,但制作类似于前面截图所示的圆角效果(这里称为内凹圆角)还是有一定难度的。用来一个更具形像的图来解释,要比我说的更清楚:
HTML Markup
在网站制作过程中,什么样的视觉效果都有可能出现,当然你可以使用图片来制作这一切效果。但在这里不考虑任何图片来实现,而且还想创造一个尽可能简洁的结构(为得是尽可能的更新快,至于会不会比图片快,我也不知道,没测试过),因此需要先创建一个模板:
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a href="#home">Home</a></li>
<li><a href="#profile">Profile</a></li>
<li><a href="#messages">Messages</a></li>
<li><a href="#settings">Settings</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="home">...</div>
<div class="tab-pane" id="profile">...</div>
<div class="tab-pane" id="messages">...</div>
<div class="tab-pane" id="settings">...</div>
</div>
这是一个典型的tabs的结构,上面的结构代码来自于Bootstrap中的Tabs部分,如果你还不了解Bootstrap,你可以先点击我了解一下。
如何制作底部的内凹圆角效果?
前面也说了,制作前面DEMO所示效果最棘手的问题是如何制作tabs菜单底部的内凹圆角效果,原因是我们无法直接使用border-radius来实现,需要使用别的形状贴出来。为了保证结构的整洁,这里考虑不添加额外的标签,而直接使用元素的伪元素(或者伪类选择器)。如果您还是第一次听说这两个概念,你可以点击这里或者这里进行了解。从本质上说,可以添加额外的标签,通过样式来实现,但是每个元素都可以有“:after”(或“::after”)和“:before”(或“::before”),因此在这里选择了他们而没有添加额外的标签,在四个选项卡中,使用了“<li>”和“<a>”两个元素的“:after”与“:before”。
接下来我们一步一步来看实现的过程:
1、默认状态
默认状态下,li是块状,a是行内元素,为了更好的显示效果,在这两个元素上先暂时添加了border样式:
2、li浮动
将li进行左浮动,列表项相互依靠在旁边,并且缩小了与内部a标签的间距:
3、相同尺寸
如果li内没有任何margin和padding值,那么li和a元素将具有相同尺寸大小
先给以上几步加上一个简单的样式:
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
4、焦点放在一个列表项上
这个时候,我们将列表项放在一个焦点之上,然后来看tabs底部内凹圆角的实现:
5、添加圆
接下来利用a的“:after”和“:before”给每个选项卡添加两个圆,先集中在一个选项卡上看效果:
这里两上圆是直接使用border-radius绘制的圆形(详细的制作方法可以点击和这里)。
接下来看实际代码带来的效果:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/ }
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
} /*制作圆角*/
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: red;
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
} .tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
此时每个列表项的前与后添加了一个圆形:
为了更好的看清楚新添加的圆,暂时在li上添加一个margin样式
接下来将圆形的颜色换成和选项卡颜色一样,并且把当前项的颜色也换回来:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30); } /*设置当前选项卡的圆形背景色*/
.nav .active a:before,
.nav .active a:after {
background: rgb(220, 225, 233);
} .nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
6、添加距形
接下来利用li的“:after”和“:before”给每个选项卡添加两个距形,先集中在一个选项卡上看效果:
同样的,将这效果应用 到每个列表项上:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
} /*添加正方形*/
.nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: red;
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
} .nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
}
.nav .active a:before,
.nav .active a:after {
background: rgb(220, 225, 233);
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
这个时候的效如下所示:
从上面的效果图中可以看出,此时的圆形和正方形层级关系并不正确,接下来,我们需要使用z-index来改变他们的层级关系:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
} .nav .active {
z-index: 3;/*当前项在最顶端*/
} .nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: red;
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/ }
.nav .active a:before,
.nav .active a:after {
background: rgb(220, 225, 233);
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
} /*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
} .tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
将颜色换正:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav .active {
z-index: 3;/*当前项在最顶端*/
}
.nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: rgb(10, 41, 30); width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/
}
.nav .active a:before,
.nav .active a:after {
background: rgb(220, 225, 233);
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
/*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
background: rgb(220, 225, 233); }
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
此时的效果就越来越接近我们需要了:
上面的效果离我们最终效果仅仅就差那么一顶点,效果图明显告诉我们,当前项的圆形背景色不能与相邻的其它选项容合,那么这一点很好办,我们只要将其背景色换成相邻选项卡的背景色一样就Ok了:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav .active {
z-index: 3;/*当前项在最顶端*/
}
.nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: rgb(10, 41, 30);
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/
}
.nav .active a:before,
.nav .active a:after {
background: rgb(10, 41, 30); }
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
/*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
background: rgb(220, 225, 233);
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
还有一个明显的问题,那就是第一个选 项卡和最后一个选项卡,圆形背景色没有处理,那么我们按同样的方法将其处理。
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav .active {
z-index: 3;/*当前项在最顶端*/
}
.nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: rgb(10, 41, 30);
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/
}
.nav .active a:before,
.nav .active a:after {
background: rgb(10, 41, 30);
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
/*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
background: rgb(220, 225, 233);
} /*第一个选项卡的:before和最后一个选项卡的:after背景色不一样*/
.nav li:first-child a:before,
.nav li:last-child a:after {
background-color: #fff;
} .tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
底部内凹圆角效果,可算是完成了,为了让效果更佳完美,给每个选项卡顶部加上圆角效果,并且将选项卡向右移动些许px:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
margin-left: 20px; }
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav .active {
z-index: 3;/*当前项在最顶端*/
}
.nav li:before,
.nav li:after {
content:"";
position: absolute;
bottom:0;
background: rgb(10, 41, 30);
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav li a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
border-radius: 10px 10px 0 0;/*给选项卡顶部添加圆角效果*/ }
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav li a:before,
.nav li a:after {
content:"";
position: absolute;
bottom: 0;
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/
}
.nav .active a:before,
.nav .active a:after {
background: rgb(10, 41, 30);
}
.nav li a:before {
left:-20px;
}
.nav li a:after {
right: -20px;
}
/*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
background: rgb(220, 225, 233);
}
/*第一个选项卡的:before和最后一个选项卡的:after背景色不一样*/
.nav li:first-child a:before,
.nav li:last-child a:after {
background-color: #fff;
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
此时的效果就完美了:
最终css代码:
.demo {
width: 660px;
margin: 20px auto;
}
.nav:after,
.nav:before {
content:"";
display: table;
}
.nav:after {
clear:both;
overflow:hidden;
}
.nav {
zoom: 1;
margin-left: 20px;
}
.nav li {
list-style: none outside none;
float: left;
position: relative;/*这个很重要*/
}
.nav .active {
z-index: 3;/*当前项在最顶端*/
}
.nav li:before,
.nav li:after,
.nav a:before,
.nav a:after {
content:"";
position: absolute;
bottom:0;
}
.nav li:before,
.nav li:after {
background: rgb(10, 41, 30);
width: 10px;
height: 10px;
}
.nav li:before {
left: -10px;
}
.nav li:after {
right: -10px;
}
.nav a {
float: left;
padding: 10px 40px;
text-decoration: none;
color: rgb(220, 225, 233);
background: rgb(10, 41, 30);
border-radius: 10px 10px 0 0;
}
.nav .active a {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
}
.nav a:before,
.nav a:after {
width: 20px;
height: 20px;
border-radius: 10px;
background: rgb(10, 41, 30);
z-index: 2;/*圆形在矩形上面*/
}
.nav .active a:before,
.nav .active a:after {
background: rgb(10, 41, 30);
}
.nav a:before {
left:-20px;
}
.nav a:after {
right: -20px;
}
/*当前项的:after和:before的z-index值为1*/
.nav .active:before,
.nav .active:after {
z-index: 1;/*当前项的矩形在圆形下面*/
background: rgb(220, 225, 233);
}
/*第一个选项卡的:before和最后一个选项卡的:after背景色不一样*/
.nav li:first-child a:before,
.nav li:last-child a:after {
background-color: #fff;
}
.tab-content {
background: rgb(220, 225, 233);
color:rgb(10, 41, 30);
padding: 20px;
}
7、添加JavaScript代码:
为了效果更像tabs选项卡效果,直接将Bootstrap的Tabs效果用上来:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="bootstrap-tab.js"></script>
<script type="text/javascript">
$(function(){
$('#myTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
})
});
</script>
同时加上对应的tabs同内容的样式:
.tab-pane {
display: none;
}
.tab-pane.active {
display: block;
}
这样一来,我们就算是大功告成了,最终效果可以点击下面的demo:
那么这个效果制作过程就算是完成了,不知道你有没有整清楚。如果没有整清楚的话不仿动手一试。
特别感谢css-tricks提供的敏捷思路——Tabs with Round Out Borders,不过这个效果还不是最佳效果,离我们最开始截的浏览器窗口效果还略有差别,不过大家放心,后面还有一个完善版本。如果您对这个感兴趣的,请观注本站的相关更新。
如需转载,烦请注昨出处:http://www.w3cplus.com/css3/tabs-with-round-out-borders.html