原本想把题目叫做“纯CSS相册2”的,但在实现过程中试验了许多东西,干脆全部写出来分享了。大家知道,能兼容IE6的具有动态切换能力的CSS属性也只有hover伪类了,但hover伪类在IE仅对链接生效,并且一定要求显式实现href属性。尽管摆在我们眼前的道路是如此坎坷,但拥有position,float,display等调整位置控制显隐的属性在手,我们还是能实现一些非常有用的东西。而且CSS是如此友善,人们不会禁用CSS吧,这就是我们用纯CSS做东西的最大理由。
提示框效果
这东西英文名为tooltip,就是我们给页面添加title属性后,当鼠标移上去时出现的小框框,里面是title的值。这是一个很有用的东西,毕竟有时我们需要各浏览器的差异,如果设计师手艺精湛也肯定看不上默认的样式。总之,无论是出于统一的需要,美观的考量,还是炫耀的目的,这东西被开发出来了。我们一起追溯整个流程,当鼠标移到某页面元素上面,提示框就出现了,不管是从上面出现,还是下面出现,左边出现亦或右边出现,就是出现。说了这么多“出现”,大家应该有足够的时间联想现场吧。移到上面,我们应该能想到hover,上下左右,我们应该有位置的概念,但能控制上下的,也就绝对定位做到(浮动只能左右)。但绝对定位,一定要求存在一个包含块。包含块当然是要提示提示框的那个部分了,我们把它设置成position:relative就行了。由于要用到hover,包含块一定要用a标签。再看提示框,它必须位于包含块里面,以获得样式切换的能力。它应该使用什么标签呢?!不用说,是span。我们只要记住,DIV用于排版,SPAN负责装饰。它们都浏览器默认样式最少的元素。好了,我们来看结构层:
其实内容纯CSS实现的提示框by 司徒正美其他内容……
表现层部分:
.tooltip {
color:#000;/*取消浏览器对a的默认样式*/
text-decoration:none;/*取消浏览器对a的默认样式*/
font-weight:700;/*用于突出重点*/
}
.tooltip span{
display:none;/*平时隐藏要放到提示框的内容*/
}
.tooltip:hover span{
display:block;/*一旦鼠标放到上面它就出现了*/
position:absolute;/*绝对定位,用于精确控制出现方位*/
white-space:nowrap;/*不允许提示框里的内容换行*/
top:1.5em;
left:2em;
background:#a9ea00;/*背景色*/
border:1px solid #10F11A;
color:#fff;
font:500 .8em/1 "Microsoft YaHei", SimSun, "Courier New";
padding:2px 1em;
-moz-border-radius: 5px;/*圆角,IE与opera没有*/
-khtml-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
cursor:text;
z-index:999;
}
.tooltip:hover{
position:relative;/*设置包含块*/
}
其他内容纯CSS实现的提示框by 司徒正美其他内容……
放大镜效果
思路和上面的基本一样,只不过包含块与隐藏部分里面的东西换成图片,并且用width与height调整图片的大小。我们先实现一个简单的东西,结构层部分:
表现层部分:
.zoom {
color:#000;/*取消浏览器对a的默认样式*/
text-decoration:none;/*取消浏览器对a的默认样式*/
}
.zoom img {
border:none;/*默认存在边框,为了精确控制,我们一般应该清除它*/
}
.zoom .small {
width:100px;/*缩小图片的宽*/
height:75px;/*缩小图片的高*/
}
.zoom span{
display:none;/*平时隐藏“放大后”的图片*/
}
.zoom:hover span{
display:block;/*一旦鼠标放到上面就“放大”图片*/
position:absolute;/*绝对定位,用于精确控制出现方位*/
top:-75px;/*此值应该为缩小图的高的负数*/
left:0px;
}
.zoom:hover{
position:relative;/*设置包含块*/
}
运行代码
好了,我解释一下CSS注释中的用引用括起“放大”的问题,用CSS强行放大图片是非常不可取的,虽然IE7搞了一个私有属性防止图片放大失真(-ms-interpolation-mode: bicubic)。我个人倾向把原图片当作“放大后”的图片,然后通过调整width与height缩小图片当作一开始我们看到的“原图”。我们现在再试试多张图片放大的情形,当作下面的纯CSS相册的热身运动了。为了便于组织这些图片,我把它们放到无序列表的LI元素中。然后取消无序列表的默认样式,利用向右浮动让其水平排序(详见运行框代码,直接查看其源码)。
运行代码
感觉有点不对劲,放大的图片把旁边的图片都遮住。如果让图片放大后自动撑开其左邻右舍呢?!但只有相同层的元素才能互相挤压推搡,很明显大图与小图并不在同一个层面。我们必须把它们放到同一层才行。
上面这段话对CSS新手可能难以理解,稍微解释一下。我们知道,当元素绝对定位或浮动后,就会脱离原来的文档流,就像一块砖头浮于大地(这时,地上就像挖了一个坑,如果是绝对定位,不会吞没这个坑,如果是浮动就会从左边或右边移动相应的体积吞没这个坑。)我们称这大地(UL元素)为第一层,上面的砖头(LI元素)为了第2层。如果不止一块砖头,并且在这些砖头还有泥土(A元素),如果当中有些泥土再被定位浮动什么的,它们就又自成一派,悬浮于更高的上空,我们称之为第3层。第4层同理。但绝对定位有点不同,就算什么变,它都是相对于其原来的位置(那个坑),而那个坑肯定是位于被定位的最近父级元素上(没有则为html)。因此如果我们给位于第4层的某个元素进行绝对定位,并且其父元素非定位元素,它不会上升为第5层。如果大地(UL元素)是定位元素,那个它就回落到第2层,如果它位于第2层的父级元素是定位元素,它则位于第3层……那么,现在大家明白层的概念不?层叠样式表可不是浪得虚名的。如果再不明白,回去啃书或学一下3D软件,3ds Max之类,增强立体想象能力。
推搡式的放大效果
基于上面的思路,我决定用浮动代替绝对定位,因为我只需要让大图在水平方向撑开其邻里。结构层不用变,只是在CSS上做些调整。
#zoom ul,#zoom li{ /*没有浮动的ul元素为第1层*/
margin:0;
padding:0;
list-style:none;
}
#zoom li{ /*浮动的li元素为第2层*/
float:left;/*实现水平排列*/
}
#zoom a{/*位于li之上的浮动a元素组成第3层*/
float:left;/*最近发现这层也不是必需的*/
}
#zoom img {
border:none;/*默认存在边框,为了精确控制,我们一般应该清除它*/
}
#zoom .small { /*位于第3层*/
width:100px;/*缩小图片的宽*/
height:75px;/*缩小图片的高*/
}
#zoom a span{
display:none;/*平时隐藏“放大后”的图片*/
}
#zoom a:hover .small{
display:none; /*悬停时,隐藏原来小图,防止大图小图并列出现。*/
}
#zoom a:hover span{/*位于li之上的浮动a元素组成第4层*/
display:block;
float:left;
cursor:pointer;
}
运行代码
为了方便大家理解,我还特意搞了个幻灯片,图解上述过程。要做出复杂的纯CSS相册,必须理解层的概念。
运行代码
滑动式纯CSS相册
由于以上的理论基础与实践经验,实现纯CSS相册不是难事。昨天我写的那个CSS是利用锚点,在opera遭遇滑铁卢,现在改由hover这个最具全平台性的CSS属性实现,绝对能成功。难点在于理解CSS的层概念。下面的相册将用“推搡式的放大效果”来改造。思路如下,相册拥有一个主显示区与翻页区,主显示区平时是空的,当我们鼠标移动到下面的翻页区的小图时,主显示区就换上相应的大图。但平时主显示区空白一片也不好吧,我们可以用背图图片(background-image)这个CSS指定为第一张图片。翻页区位于主显示区的下方,这怎样做到呢?用绝对定位,不好,因为这样需要对四张小图的top与left分别进行设置,工作量够大。我们可以用margin-top设置为大图的高,硬生生把它们挤压下去。而大图不就位于更更下方吗?是的,和运行框与放大镜的思路一样,大图是放在span中,平时隐藏。关键的步骤是当鼠标移动小图时,大图出现在margin-top留出的那片空间中,这个用绝对定位轻松实现。总的来说,它与“推搡式的放大效果”在结构层上是完全一致,表现层稍作调整,但代码量更小。
ul#album,#album li{
margin:0;
padding:0;
list-style:none;
}
#album {/*第1层*/
width:400px;/*设定相册大小,其实只是留着边框用,因为几乎所有图片都不在第一层*/
height:375px;
position:relative;
/*设定背景图片,一个障眼法而已,要不没有激活hover伪类,只有一个大空框,很难看的*/
background:transparent url(http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s001.jpg) no-repeat 0 0;
border:10px solid #EFEFDA;
}
#album li{
float:left;/*第2层*/
margin-top:300px;/*把小图挤到下面去,腾出空间给大图,因此其值为大图的高*/
}
#album img {
border:none;/*默认存在边框,为了精确控制,我们清除它*/
display:block;/*li img下方多出5px空白bug*/
width:100px;/*默认平时都以小图形式显示*/
height:75px;
}
#album a span{
display:none;/*平时隐藏大图*/
}
#album a:hover span{
display:block;/*显示相应的大图*/
position:absolute;/*绝对定位到第一个LI的内部,也可以说是UL的主窗口吧。*/
top:0;
left:0;
}
#album a:hover{
margin:0;/*修正IE6 不渲染bug,随便为其设置一种背景颜色,border,font-size,margin,让它有东西做就是*/
}
#album a:hover span img{/*第2层*/
width:400px;
height:300px;
}
运行代码