打印

[讨论] 负值z-index在IE中不再迷惑(怿飞前辈来看下)

首先,在IE和FF下分别查看一下这段代码的效果,这是怿飞前辈在《z-index在IE中的迷惑》一文中的一个例子。没有看过的人一定要看看。

 提示:您可以先修改部分代码再运行
可以看到:
FF下,黄色box1的消失;IE下,黄色box1仍然显现。
怿飞前辈在文中解释说,这是因为“IE浏览器似乎给body元素默认了一个相对定位属性(position: relative)”。
果真如此吗?看看下面这个例子:

 提示:您可以先修改部分代码再运行
CSS:
复制内容到剪贴板
代码:
*{
margin:0;
}
html{
background:silver;
}
body{
height:200px;
width:200px;
background:#0F0; /* green */
text-align:right;
opacity:0.99;   /* 去掉此行试试。*/
}
div{
position:absolute;
left:100px;
top:100px;
width:200px;
height:200px;
background:#F00; /* red */
z-index:-1;
}
其实,IE下,z-index为负值的层确实是在body下的。大概是因为body的默认背景色是transparent(我猜的,alert出来的为空),html的默认背景色是白色,而z-index为负值的层在他们之间,造成该层看起来依然在body之上的假象。
那么,为什么怿飞前辈的那个例子中,FF下z-index为负值的层没有显示呢?仔细看看我的这个例子的css ,你会发现我在body的定义中加上一句似乎无关痛痒的“opacity:0.99;”。就是这一句,使得我的例子中z-index为负值的层在FF下能显现。至于为什么,我也不知道。囧。我只是发现,只要正确设定了FF下的透明度(1除外),FF下z-index为负值的层就能显现。若设置opacity=1(小于0和大于1的情况不考虑)或不设置opacity,即使设置body的background-Color:transparent,FF下z-index为负值的层也不会显示。

IE的困惑解决了,FF下却出现了小小的困惑,呵呵。
另外还发现:
1,如果父元素设置了position为relative或absolute,并且应用了filter滤镜,其子元素超出父元素的部分就会被隐藏。IE6/IE7均有此bug。还没找到解决办法。
2,FF的透明性是可继承的,IE下position为relative或absolute的元素不继承父元素的透明性。

当然,这是题话了。
本帖最近评分记录
  • blank 威望 +2 不错的实践总结 2008-7-21 11:08

太长了,没细看

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

这个你自己可以测试,如果body有相对定位,那么body下的绝对定位就会相对body进行定位,那么你给body设置margin看看


 提示:您可以先修改部分代码再运行
测试了下,发现ie似乎给body元素默认了一个绝对定位属性(position: absolute)而且他的z-index是无限小的
而火狐似乎给body和html(被定义了样式属性时)元素默认了一个绝对定位属性(position: absolute)不过他们的z-index是0。当body的z-index值为负的时候,body内的元素z-index值再大也不会冲破他的束缚,如果body外的元素(html)定义了样式属性时,body也不会冲破这个元素的束缚

 提示:您可以先修改部分代码再运行
在路上,还要走多远

TOP

引用:
原帖由 macji 于 2008-3-13 09:14 发表
IE浏览器似乎给body元素默认了一个相对定位属性(position: relative)

这个你自己可以测试,如果body有相对定位,那么body下的绝对定位就会相对body进行定位,那么你给body设置margin看看
引用:
原帖由 kouyubo 于 2008-3-13 11:03 发表
*{
margin:0;
}
body{
height:200px;
width:200px;
background:#0F0; /* green */
text-align:right;position:absolute;z-index:-1;
}
div{
position:absolute;
left:100px;
top:100 ...
楼上二位兄弟,恐怕不是这样的。
看这个,FF/IE6/IE7下的表现是一致的。

 提示:您可以先修改部分代码再运行
可见,IE和FF下的body的position既不为relative也不是absolute。body没有设置position属性或者说是static。



把上面那个例子的css改成这个试试。
复制内容到剪贴板
代码:
*{
margin:0;
padding:0;
}
html{
background:white;
padding:25px;
width:400px;
height:400px;
border:25px solid green;
}
body{
position:absolute;
top:0;
left:0;
width:200px;
height:200px;
padding:25px;
background:silver;
border:25px solid green;
}
#a{
width:100px;
height:100px;
background:red;
}
可以发现,html元素有position的属性,但是absolute还是relative不能确定,因为只通过子元素是无法确定父元素的position是absolute还是relative的,只能确定有没有设置父元素position:relative或position:relative。

@macji:
如果body有绝对定位,那么body下的绝对定位就也会相对body进行定位,这个你也自己可以测试。所以我说通过子元素只能确定父元素是否定义position:relative/absolute,而不能确定是二者中的哪一个。


以上均未考虑position:fixed。



ps:
看到怿飞版主的ID注册的很早,以为他不小了,后来才发现原来也是80后。 称为“前辈”太夸张了 ,不好意思,版主麻烦改下。

[ 本帖最后由 zcfg 于 2008-3-13 14:04 编辑 ]

TOP

http://bbs.blueidea.com/thread-2777914-1-1.html
http://bbs.blueidea.com/thread-2683402-1-1.html

理解了FF中<body>和<html>两个特例元素的这种映射关系,该示例就很容易做出解释——你可以剥离它们的映射关系:

 提示:您可以先修改部分代码再运行
而且,FF中<html>元素就代表浏览器的视口,是无法透明的(当然你可以想象一下透明的样子,会很有趣)

最后——我现在才知道,怿飞这么年轻

[ 本帖最后由 zbm2001z 于 2008-3-13 16:24 编辑 ]

TOP

引用:
原帖由 zbm2001z 于 2008-3-13 16:15 发表
http://bbs.blueidea.com/thread-2777914-1-1.html
http://bbs.blueidea.com/thread-2683402-1-1.html

理解了FF中和两个特例元素的这种映射关系,该示例就很容易做出解释——你可以剥离它们的映射关系:
[ ...
感谢楼上的指导,让我明白了FF下html元素和body元素的映射关系。只是,我不太明白你想表达什么,或者你没明白我想表达什么?

TOP

引用:
原帖由 zcfg 于 2008-3-12 22:54 发表
……
其实,IE下,z-index为负值的层确实是在body下的。大概是因为body的默认背景色是transparent(我猜的,alert出来的为空),html的默认背景色是白色,而z-index为负值的层在他们之间,造成该层看起来依然在body之上的假象。
那么,为什么怿飞前辈的那个例子中,FF下z-index为负值的层没有显示呢?仔细看看我的这个例子的css ,你会发现我在body的定义中加上一句似乎无关痛痒的“opacity:0.99;”。就是这一句,使得我的例子中z-index为负值的层在FF下能显现。至于为什么,我也不知道。囧。我只是发现,只要正确设定了FF下的透明度(1除外),FF下z-index为负值的层就能显现。若设置opacity=1(小于0和大于1的情况不考虑)或不设置opacity,即使设置body的background-Color:transparent,FF下z-index为负值的层也不会显示。

IE的困惑解决了,FF下却出现了小小的困惑,呵呵。
——也许这个“小小的困惑”不是你想要表达的问题之一。
引用:
原帖由 zcfg 于 2008-3-13 13:45 发表
……
可见,IE和FF下的body的position既不为relative也不是absolute。body没有设置position属性或者说是static。
……
可以发现,html元素有position的属性,但是absolute还是relative不能确定,因为只通过子元素是无法确定父元素的position是absolute还是relative的,只能确定有没有设置父元素position:relative或position:relative。

@macji:
如果body有绝对定位,那么body下的绝对定位就也会相对body进行定位,这个你也自己可以测试。所以我说通过子元素只能确定父元素是否定义position:relative/absolute,而不能确定是二者中的哪一个。


以上均未考虑position:fixed。
——再来看看你表达的这个分析结论:

CSS2
9.3.1 选择定位方案:'position'属性
    'position'和'float'属性指定选择哪个CSS2定位方案来计算框的定位。

'position'
值:   static | relative | absolute | fixed | inherit  
初始值:   static  
适用于:   所有元素,除了生成的内容  
可否继承:   否  
百分比:   N/A  
媒介:   图形  

9.8.4 绝对定位
    最后,我们考虑绝对定位的效果。考虑如下的outer和inner的CSS声明:

#outer {
    position: absolute;
    top: 200px; left: 200px;
    width: 200px;
    color: red;
}
#inner { color: blue }

    这就使outer框的顶的定位基于它的包含块。定位框的包含块由最靠近的定位的前辈创建(或者,如果不存在这样的前辈,则采用初始包含块,在本例中即为如此)。outer框的顶部在包含块顶部 '200px'之下,左边在包含块左边'200px'。outer框的子框的排列相对于outer框正常排列。


再用一个参考(XHTML标签默认样式基本是基于这个规范的,所以我也只能说作为参考了)来尝试证明一下你的结论
——Appendix D. Default style sheet for HTML 4

This appendix is informative, not normative.

This style sheet describes the typical formatting of all HTML 4 ([HTML4]) elements based on extensive research into current UA practice. Developers are encouraged to use it as a default style sheet in their implementations.

The full presentation of some HTML elements cannot be expressed in CSS 2.1, including replaced elements ("img", "object"), scripting elements ("script", "applet"), form control elements, and frame elements.

For other elements, the legacy presentation can be described in CSS but the solution removes the element. For example, the FONT element can be replaced by attaching CSS declarations to other elements (e.g., DIV). Likewise, legacy presentation of presentational attributes (e.g., the "border" attribute on TABLE) can be described in CSS, but the markup in the source document must be changed.

html, address,
blockquote,
body, dd, div,
dl, dt, fieldset, form,
frame, frameset,
h1, h2, h3, h4,
h5, h6, noframes,
ol, p, ul, center,
dir, hr, menu, pre   { display: block }
li              { display: list-item }
head            { display: none }
table           { display: table }
tr              { display: table-row }
thead           { display: table-header-group }
tbody           { display: table-row-group }
tfoot           { display: table-footer-group }
col             { display: table-column }
colgroup        { display: table-column-group }
td, th          { display: table-cell }
caption         { display: table-caption }
th              { font-weight: bolder; text-align: center }
caption         { text-align: center }
body            { margin: 8px }
h1              { font-size: 2em; margin: .67em 0 }
h2              { font-size: 1.5em; margin: .75em 0 }
h3              { font-size: 1.17em; margin: .83em 0 }
h4, p,
blockquote, ul,
fieldset, form,
ol, dl, dir,
menu            { margin: 1.12em 0 }
h5              { font-size: .83em; margin: 1.5em 0 }
h6              { font-size: .75em; margin: 1.67em 0 }
h1, h2, h3, h4,
h5, h6, b,
strong          { font-weight: bolder }
blockquote      { margin-left: 40px; margin-right: 40px }
i, cite, em,
var, address    { font-style: italic }
pre, tt, code,
kbd, samp       { font-family: monospace }
pre             { white-space: pre }
button, textarea,
input, select   { display: inline-block }
big             { font-size: 1.17em }
small, sub, sup { font-size: .83em }
sub             { vertical-align: sub }
sup             { vertical-align: super }
table           { border-spacing: 2px; }
thead, tbody,
tfoot           { vertical-align: middle }
td, th          { vertical-align: inherit }
s, strike, del  { text-decoration: line-through }
hr              { border: 1px inset }
ol, ul, dir,
menu, dd        { margin-left: 40px }
ol              { list-style-type: decimal }
ol ul, ul ol,
ul ul, ol ol    { margin-top: 0; margin-bottom: 0 }
u, ins          { text-decoration: underline }
br:before       { content: "\A" }
:before, :after { white-space: pre-line }
center          { text-align: center }
:link, :visited { text-decoration: underline }
:focus          { outline: thin dotted invert }

/* Begin bidirectionality settings (do not change) */
BDO[DIR="ltr"]  { direction: ltr; unicode-bidi: bidi-override }
BDO[DIR="rtl"]  { direction: rtl; unicode-bidi: bidi-override }

*[DIR="ltr"]    { direction: ltr; unicode-bidi: embed }
*[DIR="rtl"]    { direction: rtl; unicode-bidi: embed }

@media print {
  h1            { page-break-before: always }
  h1, h2, h3,
  h4, h5, h6    { page-break-after: avoid }
  ul, ol, dl    { page-break-before: avoid }
}

最后,请楼主原谅我的愚笨——在我之前的回复中,原以为不需要再引用这些啰嗦的规范了

[ 本帖最后由 zbm2001z 于 2008-3-14 10:36 编辑 ]

TOP

@zbm2001z:
事情被搞复杂了,其实是这样的:我一开始没搞明白你在#6楼发那段代码的意图是什么,只是看了你给的两个链接,所以才有#7楼的回复。然后你误解了我在#7楼回复的意图,才有#8楼的回复==! 。

现在我再回头看了发下你在#6楼的那段代码,才明白,你想表达的是:在FF下,如果没有设置html元素的css,那么给body元素设置的样式就会映射到html元素上,所以z-index为-1的div(body的子元素)才会看起来仍旧显示在body上方(实际上不是)。
你的目的是解决我所说的在“FF下的小小困惑”,是吧?其实我发这篇帖子的目的是想说明一些问题,而不是为了提出问题,呵呵。

最后,非常感谢你的回复,非常感谢。

TOP

其实也只是顺便想说明一些问题:
1.熟读标准中规范的定义
2.了解各浏览器开发人员对规范的理解不同,从而造成解析上的差别(这里不是指BUG)
3.标准本身在制定上可能存在的缺陷(比如晦涩难懂、缺少更多的示例等等),以及由此而引发的争议

最后,也非常认同你的钻研精神,希望我这个可能老点的鸟对这种精神有一点点帮助

TOP

回头看了这篇文章才发现了某些价值的存在,加分已示鼓励。
个人Blog:PlanABC   团队Blog:淘宝UED  专注Web前端技术!

TOP