CSS属性"opacity"的古怪行为

7
在完成一个任务时,我需要在可滚动面板的顶部有一个固定位置的工具栏,然后我发现了CSS属性“opacity”的这种古怪行为。
这个简单的演示很容易理解,但总结一下: 如果你有两个DIV,一个是固定位置的,另一个在固定的DIV后面滚动,那么透明内容(opacity <1)在可滚动的DIV中显示在固定的DIV上方。 这里固定DIV的不透明度没有任何影响。
虽然如果我给固定的DIV分配比可滚动的DIV更大的z-index(请参见此演示),问题就会消失,但我仍然想知道为什么在这种情况下,不透明度属性的行为是反直觉的。
可以有人解释一下吗?
顺便说一下,这种行为在Chrome 35、FF 30和IE 10中保持一致。
将代码从jsfiddle复制到这里-因为这是惯例。 CSS
.fixedOpaqueDiv {
    position: fixed;
    background-color: #ABABAB;
    width: 100%;
    height: auto;
    text-align: center;
    font-size: 20px;
    color: #DDDDDD;
    padding-top: 5px;
    opacity: 1;
}
.scrollingDiv {
    padding-top: 140px;
    text-align: center;
    color: blue;
    font-weight: bold;
}

.opaque {
    opacity: 1;
}

.translucent {
    opacity: 0.5;
}

HTML

<div style="height: 300px; overflow: auto;">
    <div class="fixedOpaqueDiv">I am a div with fixed position,
        <BR>with same z-index as the div below.
        <BR>I am supposed to be Opaque, but
        <BR>apparently I am opaque ONLY to the opaque divs below,
        <BR>and not to the translucent ones</div>
    <div class="scrollingDiv">
        <div class="translucent" style="color: red; padding: 5px;">^^^^^^^^ Scroll up ^^^^^^^^</div>
        <div class="opaque">Opaque 1</div>
        <div class="translucent">Translucent 1</div>
        <div class="opaque">Opaque 2</div>
        <div class="translucent">Translucent 2</div>
        <div class="opaque">Opaque 3</div>
        <div class="translucent">Translucent 3</div>
        <div class="opaque">Opaque 4</div>
        <div class="translucent">Translucent 4</div>
        <div class="opaque">Opaque 5</div>
        <div class="translucent">Translucent 5</div>
        <div class="opaque">Opaque 6</div>
        <div class="translucent">Translucent 6</div>
        <div class="opaque">Opaque 7</div>
        <div class="translucent">Translucent 7</div>
        <div class="opaque">Opaque 8</div>
        <div class="translucent">Translucent 8</div>
    </div>
</div>

一个有趣的效果,但是在具有相同z-index的两个重叠元素中请求不可预测的行为,就像在3D图形中当你有两个平面在同一位置时一样。 - Niet the Dark Absol
同意。两个DIV具有相同的z-index,因为我没有明确地分配任何一个给它们。一段时间内一切都正常,因为滚动面板中没有半透明内容,问题只在某人皮肤化了可滚动面板并且一些半透明内容进入后才显现出来。理想情况下,问题应该从一开始就显现出来。 - Alphonso
1个回答

8
这与 透明度小于1的元素会创建一个层叠上下文有关。没有建立层叠上下文的元素将被您的固定位置元素遮挡,但是建立了层叠上下文的半透明元素将在前面绘制,因为它们在源文件中出现在固定位置元素后面。
设置 z-index 的原因是使固定位置元素的堆栈级别大于可滚动元素内容的堆栈级别。 CSS2.1规范第9.9节总结了元素叠加的确切顺序。列表中的最后两项与此方案相关:

在每个层叠上下文中,以反向顺序绘制以下图层:

  1. 形成层叠上下文的元素的背景和边框。
  2. 具有负堆栈级别的子叠加上下文(最负面的优先)。
  3. 非内联级别、非定位后代。
  4. 未定位浮动。
  5. 内联级别的非定位后代,包括内联表格和内联块。
  6. 堆栈级别为0的子叠加上下文和堆栈级别为0的定位后代。
  7. 具有正堆栈级别的子叠加上下文(最少的正数)。
在 #6 中,“子叠加上下文”是指半透明元素,而定位后代是固定元素。一旦您在固定元素上设置了 z-index,它就落在第7项下,这确保它将显示在半透明内容上方。

非常有趣。感谢指引我正确的方向。 所以在我的情况下,叠加上下文(由于透明度而创建)胜过了固定位置的 div,仅仅是因为它出现在 HTML 中后面。 我通过将它们在 HTML 中的顺序颠倒(并向固定定位的 div 添加“top: 0px”)来验证这一点,并获得了期望的效果,而无需为定位的 div 分配 z-index - 在这里查看。 - Alphonso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接