收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 12489|回复: 11

[教程] 元素层叠级别(stack level)及z-index剖析

[复制链接]
发表于 2008-7-18 20:02:47 | 显示全部楼层 |阅读模式
声明

定位元素:position属性值设置除默认值static以外的元素,包括relative,absolute,fixed。
平台:win/IE win/FF


z-index:

用来确定定位元素在垂直于显示屏方向(以下称为Z轴)上的层叠顺序

    值:      auto | 整数 | inherit
    默认:      auto
    适用于:  定位元素
    继承性:  no

理解stacking context

每个box都归属于一个stacking context,它是元素在z轴方向上定位的参考。根元素形成 root stacking context,其他stacking context由定位元素设置z-index为非auto时产生。如#div1{position:relative;z-index:0;}即可使 id=div1的元素产生stacking context。stacking context和 containing block 并没有必然联系。

理解stack level

在一个stacking context中的每个box,都有一个stack level(即层叠级别,以下统一用stack level),它决定着在同一stacking context中每个box在z轴上的显示顺序。同一stacking context中,stack level值大的显示在上,stack level值小的显示在下,同一stack level的遵循后来居上的原则(back-to-front )。不同stacking context中,元素显示顺序以父级的stacking context的stack level来决定显示的先后情况。于自身stack level无关。注意stack level和z-index并不是统一概念。(将在后文慢慢理解)

stack level规则

每个stacking context中可包含块级(block)元素、内联(行内inline)元素,还有设置float属性的元素、定位元素等等他们在同一父级 stacking context中的显示顺序是怎样的?即stack level是怎样的呢?比如一个块级元素和内联元素发生层叠的话谁会在上面呢?是不是谁在后面谁就在上面呢?

根据w3c关于stack level的介绍可以得出以下stack level规则

每个stacking context都包括以下stack level (后来居上):

    1.父级stacking context的背景、边界
    2.z-index值为负值的定位元素(值越小越在下)
    3.文本流中非定位的、block块级子元素
    4.文本流中非定位的、float浮动子元素
    5.仿佛能产生stacking context的inline元素
         否则,inline元素的stack level将在block元素之前。
    6.z-index:auto/0的定位元素
    7.z-index值为正的定位元素(值越大越在上)

以上stack level在浏览器执行情况:
firefox3.0下测试完全吻合,firefox2.0下稍有不同即:“z-index值为负值的定位元素”在“父级stacking context的背景、边界”之前。
ie6.0和7.0中:inline元素的stack level位于block元素之前,且“文本流中非定位的、float浮动子元素”(以下简称浮动元素)和“文本流中非定位的、block块级子元素”(以下简称block元素)处于同一级。

[[i] 本帖最后由 rong179 于 2008-7-18 20:52 编辑 ]

评分

参与人数 2威望 +4 收起 理由
blank + 2 分析很经典,赞
phantom + 2 我很赞同

查看全部评分

 楼主| 发表于 2008-7-18 20:03:14 | 显示全部楼层
测试:

FF下测试:

 提示:您可以先修改部分代码再运行



测试页面:

http://rong179.blogbus.com/files/12163574750.html(请分别在FF3.0和FF2.0中打开)


代码说明:

由前所述,如果元素的stack level同级则后来居上;元素的stack level高,这无论代码在文档中位置如何都显示在上面,即使代码在最前面;如果元素的stack level低,无论代码位置如何都将显示在下面,即使代码在最后面。

我们就根据这一点,以“3.文本流中非定位的、block块级子元素”和“4.文本流中非定位的、float浮动子元素”为例,如果我把“float元素” 的代码写在“block元素”的前面,且实际显示为:“float元素”在“block元素”之上。即可证明:"float元素”的stack level级别较“block元素”高。因为如果同级,或者“block元素”的stack level高都应是“block元素”显示在上。

根据以上,根据标准中的顺序,把stack level高的元素代码写在前面,stack level低的代码写在后面,如果显示结果是:代码在前面的元素显示在上方 ,即证明上面的stack level规则。

测试结果:

在FF3.0中结果和标准顺序一致。FF2.0中“z-index值为负值的定位元素”在父级stacking context的背景下面。(注意ff2.0的这个特殊性)



IE下测试:

 提示:您可以先修改部分代码再运行



测试页面:

http://rong179.blogbus.com/files/12163574751.html(请在IE下浏览)

代码说明:

此代码也是根据上面的测试思想,但由于inline元素在ie中的特殊性,把inline的代码写在了后面,事实证明结论是正确的。对于“block元素”和“float元素”顺序大家可以交换顺序测试。
测试结论:

IE下(无论ie6.0或者ie7.0)“float元素”和“block元素”属同一stack level,而“inline元素”较其stack level低。

解释:

“float元素”,“z-index:auto的定位元素”仿佛产生了新的stacking context,但其真正能产生新的stacking context的后代任按其父级stacking context定位。(但IE中“z-index:auto的定位元素”
会拥有z-index值0,产生一个新的stacking context,并影响其子元素定位。这是IE一个BUG)
inline元素在FF中仿佛能产生新的stacking context,而在IE中则不能。

至此stack level规则内容已经完毕,现在应该能理解stack level和z-index的不同。stack level来决定这一个stacking context中各元素在z轴上的显示顺序,对于同一stack level的定位元素才由z-index进一步决定显示次序。

[[i] 本帖最后由 rong179 于 2008-7-18 20:50 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-18 20:04:23 | 显示全部楼层
一些问题的解释:
怿飞版主在《z-index在IE中的迷惑》一文中最后提到的问题:

 提示:您可以先修改部分代码再运行



演示地址:

http://rong179.blogbus.com/files/12163573190.html

认为:

   
解惑:IE浏览器似乎给body元素默认了一个相对定位属性(position: relative)。



真是这样吗?

 提示:您可以先修改部分代码再运行



演示地址:

http://rong179.blogbus.com/files/12163572440.html


分析:

box1显示在body的下方,根据上面的stack level规则,IE中,如果body默认了一个位置属性,即body是其父级stacking context,box1应显示在其上方,事实却不是这样。而且当我们给body加上position:relative以后,显示效果和stack level规则一致。所以body并没有默认位置属性。

那为什么负值的定位元素在IE和FF下显示不一致呢?

ie 中根据stack level规则: z-index为负的定位元素的stack level比父级stacking context(此处是root stacking context)高,显示在其上方。故box1在ie中能显示。ff3.0和标准一致,也能显示。大家可以试一下。

ff2.0 中由于那条特殊的stack level,即 z-index为负的定位元素的stack level比父级stacking context(此处是root stacking context)低,所以显示在root stacking context下方。故不能看见。

另外,上面的代码中加上opacity那条后,在ff2.0中即可显示了。这又是什么原因呢?

推测:在火狐中如果给元素设置opacity属性(1除外),即会产生新的stacking context。

上面加上opacity属性后在ff2.0中可显示box1在body下,ff3.0box1在body上,(可以根据上面的stack level规则自己分析)符合推测。
在w3c的说明中也证明这点

  
In future levels of CSS, other properties may
    introduce stacking contexts, for example 'opacity'
    [CSS3COLOR].


总结:

在一个stacking context中元素的z-轴显示顺序,由元素所处的stack level决定。对于同一stack level的定位元素由z-index的大小进一步决定显示次序。

       
  • ie中给元素设置position属性(static除外)可产生新的stacking context
       
  • ff中给元素设置opacity属性(1除外)可产生新的stacking context

除此之外(也许设置其他属性也会产生新的stacking context,但还不知道)只有定位元素设置了z-index(auto除外)才会产生新的stacking context,子元素将按照新的stacking context,定位。


相关文章/讨论:

  z-index在IE中的迷惑
  Elaborate description of Stacking Contexts
  负值z-index在IE中不再迷惑(怿飞前辈来看下)

BLOG阅读处:http://rong179.blogbus.com/logs/24966909.html

[[i] 本帖最后由 rong179 于 2008-7-18 20:45 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2008-7-18 22:06:09 | 显示全部楼层
好帖,赞个~
回复 支持 反对

使用道具 举报

发表于 2008-7-19 21:14:08 | 显示全部楼层
同楼上,我终于明白了.....
回复 支持 反对

使用道具 举报

发表于 2008-7-21 09:59:19 | 显示全部楼层
本人还是菜鸟,不大明白,学习中.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-21 10:37:52 | 显示全部楼层
不好意思,写的比较枯燥 。2# 测试部分可以先跳过读。
回复 支持 反对

使用道具 举报

发表于 2008-7-21 11:13:16 | 显示全部楼层
文章分析得比我严谨,谢谢您的分享。其实在我的文章中,也仅是猜测:“IE 浏览器似乎给 body 元素默认产生了stacking context。”,所有用了“似乎”一词。当时没有去深究,产生了某些误导,很歉意。
回复 支持 反对

使用道具 举报

发表于 2008-7-23 22:50:28 | 显示全部楼层
很精辟!赞个!

理解的更加透彻了...
回复 支持 反对

使用道具 举报

发表于 2008-7-24 15:43:51 | 显示全部楼层
http://www.tjkdesign.com/article ... _elements_stack.asp
这个网页上有关于z-index的一个很好的演示
大家可以看看

赞楼主 虽然我现在还看不太懂
回复 支持 反对

使用道具 举报

发表于 2008-8-29 09:59:56 | 显示全部楼层
仔细看了看,很不错,E资料来自哪里啊?
回复 支持 反对

使用道具 举报

发表于 2008-8-29 13:58:40 | 显示全部楼层
可以再继续深入一下,特别是对IE。深入后补全了会更完整一些。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( ICP05002321 )  

GMT+8, 2019-5-27 15:26 , Processed in 0.093750 second(s), 10 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表