如果我我们设定LI为position:relative;设置span为position:absolute;那么我们会发现无论SPAN的z-index值设置得再高都将永远在后面父级的下面。
前段时间记得好像是谁在群里提出了一个实在是让大家都觉得很不理解的一个问题:
<ul> <li>第一块</li> <li><span>第二块</span></li> <li>第三块</li> <li>第四块</li> <li>第五块</li> </ul>
如果我我们设定LI为position:relative;设置span为position:absolute;那么我们会发现无论SPAN的z-index值设置得再高都将永远在后面父级的下面。
*{margin:0; padding:0; list-style:none;} li {width:100px; height:100px; margin:0 5px 0 0; background:#000; float:left; position:relative; z-index:1;} li span {width:200px; height:100px; background:#c00; position:absolute; top:0; left:100px; z-index:1000;}
试一下很容易发现我们的子级,z-index的值达到了1000的被设定了position:absolut;子级都被档在了父级的下面。我想了很久,我觉得其根本问题是:设置同样的position:relative/absolute;同级标签之间的等级是无法用z-index超越的。我们上面的例子中的第一个LI的等级永远都要小于后一个LI的等级,所以我们在LI里的子级身上设置了position:absolute;,给了非常高的z-index值。
也许你会这样来想:只要针对有span的LI设置position:relative;不就好了吗?非常正确。当其它的LI都不设置position:relative;那么我们需要的那个子级就可以浮在所有的内容之上。但是如果实际上,所有的LI中都要有span,并且属性都需要一样怎么办?当然我们不大会需要有这样的效果。但是我们需要有这样的效果:子级全部是隐藏的,当有鼠标反应时出现并且浮在所有的内容之上。我们要知道,这确实是件让人头疼的事,因为我们上面见识到了,子级在显示的时候都被压在了下一个父级标签的下面。下面我们来实现一下这个鼠标反应的定位效果:
<ul> <li><a href="" title=""><span>第一块</span></a></li> <li><a href="" title=""><span>第二块</span></a></li> <li><a href="" title=""><span>第三块</span></a></li> <li><a href="" title=""><span>第四块</span></a></li> <li><a href="" title=""><span>第五块</span></a></li> </ul>
我们通过链接的鼠标事件来完成这个显示隐藏效果:
*{margin:0; padding:0; list-style:none;} li {height:100px; margin:0 5px 0 0; float:left; width:100px;} li a {position:relative; z-index:1; display:block; height:100px; width:100px; background:#000;} li a:hover {background:#000000;} li span {display:none;} li a:hover span {display:block; background:#c00; width:200px; height:200px; position:absolute; top:0; left:100px; z-index:1000;}
我们设定了a为position:relative;这样他的子级就会根据父级的左上角为坐标原点进行定位了。然后我们设定span的具体形状以及定位属性,然后把他隐藏了。我们再通过A的伪类:hover使得span被激活。我们看一下结果,我们会发现,所有应该在上面的现在全在下面了。那我们怎么解决这个难题呢,其实以CSS想强行突破是不太可能,所以我们反过来想,能不能让这个没有被触发的父级标签没有position:relative;属性,而只是触发的时候才有级这个父级赋上这样的值?其实想到这里基本上已经可以解决所有的问题了:
*{margin:0; padding:0; list-style:none;} li {height:100px; margin:0 5px 0 0; float:left; width:100px;} li a {display:block; height:100px; width:100px; background:#000;} li a:hover {position:relative; z-index:1; } li span {display:none;} li a:hover span {display:block; width:200px; height:200px; background:#c00; position:absolute; top:0; left:100px; z-index:1000; }
我们只要针对a:hover来设定其属性为position:relative;就可以了,这样只有在鼠标触发的时候A才会被赋于一个相对定位的属性。这样就完成可以解决被其它父级标签所挡的尴尬了。
当然如果不介意IE5这样的浏览器我们还可以把代码再做简化:
<ul> <li><span>第一块</span></li> <li><span>第二块</span></li> <li><span>第三块</span></li> <li><span>第四块</span></li> <li><span>第五块</span></li> </ul>
CSS可以改成这样:
*{margin:0; padding:0; list-style:none;} li {height:100px; margin:0 5px 0 0; float:left; width:100px; background:#000;} li:hover {position:relative; z-index:1;} li span {display:none;} li:hover span {display:block; width:200px; height:200px; background:#c00; position:absolute; top:0; left:100px; z-index:1000; }
补充:
前些时间发表的《position:relative/absolute无法冲破的等级》一文,讲了定位中的等级,这几天再看的时候发现文中讲得并不透彻,没有直指关键。所以特别的在这里做出补充希望能把position中的等级讲得更为清楚、明确一些。
我们都知道,position有四个不同的值,分别为:static | absolute | fixed | relative。在苏昱的《CSS2中文手册》中是这样解释的:static:无特殊定位,对象遵循HTML定位规则; absolute:将对象从文档流中拖出,使用left,right,top,bottom等属性进行绝对定位。而其层叠通过z-index属性定义。此时对象不具有边距,但仍有补白和边框; relative:对象不可层叠,但将依据left,right,top,bottom等属性在正常文档流中偏移位置; fixed:IE5.5及NS6尚不支持此属性。
但是要想改变对象的层叠位置需要的是另一个CSS属性:z-index。但是这个z-index并非是无所不能的,他受到了HTML代码等级的制约。z-index只能在同等级的HTML上体现他的作用。这里需要声明的是z-index只有在对象的position值为relative/absolute时才可以使用。下面我们就举些例子来解释等级的特性:
<p id="box_1"> <p id="a">这是第一个块</p> <p id="b">这是第二个块</p> </p>
针对上面的这个HTML代码我们还需要写一段CSS来定义它:
#a,#b {position:absolute; width:300px; height:100px; } #a {z-index:10; left:0; top:0; background:#000; } #b {z-index:1; left:20px; top:20px; background:#c00; }
这是最普通的在这种情况下#a与#b的层叠等级是可以通过z-index来设定的。这是没问的,那么什么样的情况下就会出现问题呢?我们再看一个实例:
<p id="box_1"> <p id="a">这是第一个块</p> </p> <p id="box_2"> <p id="b">这是第二个块</p> </p>
根据这个结构再写一个CSS,要注意这个CSS中的不同的地方:
#box_1, #box_2 {position:relative; width:300px; height:100px; margin:10px; background:#ddd;} #a, #b {position:absolute; width:100px; height:300px; } #a {background:#c00; z-index:100; } #b {background:#0c0; z-index:1; left:50px;}
这时候我们看,不论#a设为多大的值,他都无法超过#b,所以说z-index是无法冲破HTML的等级的,他必需是要同等级的状态下才可以发挥威力.那么如何解决这个问题呢?我可以反过来想,堂兄弟之间的顺序不能被重组,何不把父辈的等级做一次重组呢?所以我们把#box_1的CSS中加入一个z-index:100; 在#box_2的CSS中加入z-index:1;这样再看一下效果:
#box_1, #box_2 {position:relative; width:300px; height:100px; margin:10px; background:#ddd;} #box_1 {z-index:100;} #box_2 {z-index:1;} #a, #b {position:absolute; width:100px; height:300px; } #a {background:#c00; } #b {background:#0c0; left:50px;}