拥有阴影并且能自适应的弹出层

依稀记得今天所要与大家分享的这点内容是以前在迅雷工作的时候,大仙曾与几位重构师分享过,不过当时并没十分在意,只是依稀记得大致的实现方式,这次自己再在这个大致的实现方式上去实验,最终将结果分享出来供大家批斗,不妥的地方请大家多多提意见。

弹出层是现在网站中使用率很高的一个效果,有半透明的黑屏中叠加一个层,也有弹出层的旁边出现透明边框的方式。总之呢,形式呢是多姿多彩,但基本的原理都是差不多,小志这次要跟大家分享的并不是面面俱到的所有方式的弹出层,而是一个拥有阴影(或者说是透明边框)并且能自适应宽高的弹出层。

实现的方式有几种,但为了页面的整体性能会对IE进行选择性的舍弃。废话不多说了,先来看一下大概的页面表现效果吧。

>>>点击查看demo<<<

如果是使用IE6的同学看到这个页面的时候,肯定会说“骗子,边框是灰色的,哪有什么透明啊”。是的,在IE6中大家看到的边框是灰色的,而并非是半透明的效果。假如IE6支持PNG-32的alpha透明效果,那么大家在IE6中看到的也就是一个透明的边框了,可惜IE6却不支持。

可不要说使用透明的滤镜(Alpha)或者让IE6支持PNG-32透明的那个滤镜(AlphaImageLoader)哦,个人对滤镜这个东西实在有点怕怕的,曾经用了AlphaImageLoader这个滤镜之后,在IE6中拖动弹出层时,那个卡啊,就好像386机器上运行极品飞车。不过如果大家一定要让IE6出现透明的效果的话,那就用透明滤镜(Alpha)吧,相对比AlphaImageLoader滤镜要好一点。

效果我们看过了,那么对于目前这个demo我们的实现方式是怎么样的呢,其实很简单啦,先来看一下思路:

  1. 结构主要是由“标题”、“内容”、“按钮区域”三个部分组成;
  2. 为了能更好的实现透明边框效果,需要附加一个空标签作为实现透明效果的容器
  3. 透明效果的容器必须定位在弹出层内容的底部,因此我们必须使用的是定位的属性
  4. 当使用了定位的属性后,如何保证透明层以及内容层的宽高完美结合

有了这么一个整体的思路之后,我们再分步推敲一下实现的方式:
1、为了有透明的效果,那么一个透明的层在最底下是必须的

弹出层的透明底

弹出层的透明底

2、然后增加一个存放弹出层内容的容器

弹出层增加内容包含的容器

弹出层增加内容包含的容器

3、最后需要的就是弹出层的内容部分了哦

弹出层增加内容区域后

弹出层增加内容区域后

根据这样的一个整体思路之后,我们要做的就是写XHTML结构了

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="pop_wrap" style="width:400px;top:50px;left:100px;">
	<!-- 弹出层内容 开始 -->
	<div class="pop_container">
		<h3 class="pop_header"><span>标题</span></h3>
		<div class="content">
			<p>这里放内容</p>
		</div>
		<a href="#" class="close">关闭</a>
		<div class="btn"><button type="button">这是按钮</button></div>
	</div>
	<!-- 弹出层内容 结束 -->
	<div class="bg"></div>
</div>

在这个结构中我们可以看到主要是有上面思路中所预定的层叠关系来设置的className是pop_wrap的div标签作为弹出层的主要容器,其中包含了style属性,该属性中有宽度值以及弹出层定位后显示位置的top和left值;其次我们可以看到className是pop_container的div标签中包含了标题、内容、关闭、弹出层操作按钮;最后还有一个className是bg的div标签是一个空标签,其主要作用是显示透明背景。

这样的一个结构简化之后其实就是
div class="pop_wrap"
 div class="pop_container"
 div class="bg"

OK,现在我们结构已经有了,下面要做的就是要写样式了,样式呢主要是通过定位的方式实现,需要注意的有这么几点:

  1. 透明层在IE6中我们使用灰色的背景;在高于IE6的IE浏览器以及非IE浏览器我们可以是使用PNG-32图片平铺实现
  2. 两个同时定位的弹出层我们无法同时利用一个宽度或者高度值使它们同时改变,因此我们可以考虑预先设置一个比较大的属性值给背景层,减少JS开发中的赋值次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
* {margin:0;padding:0;font:normal 12px/1.5em simsun, Verdana,Lucida, Arial, Helvetica, sans-serif;}
body {background:url(img/bg.gif) repeat 0 0;}
.pop_wrap:after,
.pop_wrap .bg:after,
.pop_container:after {content:"";display:block;height:0;clear:both;visibility:hidden;font-size:0;line-height:0;}
 
.pop_wrap {position:absolute;overflow:hidden;padding:7px;zoom:1;z-index:999;}
.pop_container {position:relative;border:1px solid #ADADAD;background-color:#FFFFFF;zoom:1;z-index:5;}
.pop_wrap .bg {position:absolute;top:0;left:0;height:100%;padding:500px;background:url(img/bg_alpha.png) repeat 0 0;_background:#CCCCCC;zoom:1;}
 
.pop_wrap h3 {height:29px;line-height:29px;text-indent:11px;font-size:14px;border-bottom:1px solid #DFDFDF;background-color:#F1F1F1;}
.pop_wrap h3 span {line-height:29px;}
.pop_wrap .btn {clear:both;height:21px;padding:11px 0;text-align:right;border-top:1px solid #DFDFDF;background-color:#F1F1F1;}
.pop_wrap .btn button {margin-right:10px;cursor:pointer;}
.pop_wrap .close {position:absolute;top:6px;right:10px;color:#FF0000;z-index:5;}
.pop_wrap .close:hover {text-decoration:none;color:#000000;}
 
.pop_wrap .pop_container .content p {padding:50px;}

这样我们就能得到最终想要的一个页面效果,也就是刚刚我们所看到的demo页面了。

为了能让大家更容易理解样式的含义,在这里小志简单地说明一下主要部分的样式:

1
.pop_wrap {position:absolute;overflow:hidden;padding:7px;zoom:1;z-index:999;}

绝对定位,但未设置top、left、right、bottom的属性值,这几个属性值我们留在div的style属性中书写,由JS程序人员控制;
内补丁7px是为了能让隔离内容区域,显示透明背景层;
overflow:hidden;zoom:1;分别主要作用是清除自身浮动,自适应高度而设定的;
z-index:999;这个就更容易理解啦,设置比较大一点的值,当弹出层在页面中出现的时候,不会被其他弹出层覆盖

1
.pop_container {position:relative;border:1px solid #ADADAD;background-color:#FFFFFF;zoom:1;z-index:5;}

设置相对定位的属性是为让其子级元素在定位的时候具有参照的对象,并且同时让该元素具备层叠属性,与透明背景层形成层叠的关系;
增加背景色以及边框颜色当然是为了这个弹出层更加美观,可惜小志不是设计师,视觉效果不好,^o^;

1
.pop_wrap .bg {position:absolute;top:0;left:0;height:100%;padding:500px;background:url(img/bg_alpha.png) repeat 0 0;_background:#CCCCCC;zoom:1;}

这个是要重点介绍的对象了哦,绝对定位是必须要的,不然这个透明的底层怎么可能会跑到内容区域下面呢;
padding:500px;这个是不是很奇怪呢,其实不用奇怪的,因为padding值是可以显示该容器的背景属性的,我们既然没设置宽高属性,那么就用padding值来顶开来吧,在标准模式下,padding值还是会有作用的;
bg_alpha.png是具有alpha透明通道的png-32图片,也就是我们所看到的透明效果,然后对于IE6的话,我们仅仅只要灰色就可以了,也就是_background:#CCCCCC;

那么我们所做的一切现在就完工了,剩余的内容就是看我们可爱的程序员需要多大的弹出框,以及弹出框需要定位在页面中的什么位置;而弹出框的内容部分我们可以直接在className为content的div标签中书写,怎么写就是大家个人的喜好了。说白了,我们完全可以当这个弹出框是一个弹出层的模板,把样式丢到公共部分,只要保证最外层的className为pop_wrap的div标签不会与页面中的其他模块冲突就得了。

提示:如果大家觉得用图片不爽的话,其实还真的是有点不爽,如果需要修改透明的颜色什么的还是有些不方便,那么大家可以用透明滤镜(IE以及非IE浏览器都有这个属性),这样修改颜色值就会十分的方便了。

1
.pop_wrap .bg {position:absolute;top:0;left:0;height:100%;padding:500px;background-color:#333333;filter:alpha(opacity=30);opacity:0.3;zoom:1;}

>>>点击查看使用滤镜的demo<<<

现在CSS3的出现,我们如果能利用的而不去利用的话,实在是有点说不过去了,那么现在我们来看看如果我们使用CSS3的方式实现又将会是如何呢。

1
.pop_wrap .bg {position:absolute;top:0;left:0;height:100%;padding:500px;background:rgba(33,33,33,0.3);*background-color:#333333;*filter:alpha(opacity=30);zoom:1;}

>>>点击查看使用rgba属性和IE滤镜后的demo<<<

这里我们使用的是rgba属性,而IE不支持么,我们只好继续使用滤镜的方式顶一下了。对于rgba属性呢,使用的是rgb的颜色值,a则是透明度。

使用了CSS3,那么我们可以更加疯狂一点,CSS3可不是只有一个rgba属性啊,还有box-shadow属性哦,阴影边框,太酷了。这个阴影边框我们无需使用className为bg的这个div标签,而直接使用在container上就可以了;可惜我们多少还是要照顾一下IE浏览器,那么我们就这样操作吧。

1
2
.pop_container {position:relative;border:1px solid #ADADAD;background-color:#FFFFFF;-webkit-box-shadow:5px 5px 5px #333333;-moz-box-shadow:5px 5px 5px #333333;zoom:1;z-index:5;}
.pop_wrap .bg {position:absolute;top:0;left:0;height:100%;padding:500px;*background-color:#333333;*filter:alpha(opacity=30);zoom:1;}

>>>点击查看使用box-shadow属性和IE滤镜后的demo<<<

扯了这么多,基本上要说的已经说完了,以上效果仅仅只是在FF3.6和IE7中测试,可怜的机子中未安装IE8,绿色版的IE6又不支持滤镜,但不想开IETESTER,至于其他浏览器嘛,装是装了,基本上FF上能正常显示这些效果的话,其他浏览器也是OK的。还有其他什么的360浏览器啊就不要测试了,更不要说是在DW里测试,没啥意义,如果大家一定要测试的话那我也没办法,毕竟小志在这里跟大家说的只是一个想法一个思路,怎么用那就需要各位看官来把控了。

关于CSS3的相关内容大家可以查看ISD团队为大家提供的CSS3手册http://isd.tencent.com/?p=1252

如果觉得这篇日志还OK,要转载的朋友呢,烦请同情一下小志辛苦的劳动,留个链接地址吧。

有话要说