不透明度如何影响元素顺序?

3

我发现了一种关于CSS opacity 与浮动元素相结合的非常奇怪的行为。
考虑以下HTML:

<div style="position: relative; clear: both">
   <div style="float:left>Left button</div> 
   <div style="float:right>Right button</div>  
</div>
<div style="opacity: 0.9">Overlay</div>

最后一个 div 会覆盖前两个浮动的 div。移除不透明度将使最新的 div 在浮动的 div 下面。
这是在我的实际页面上的效果(红色背景仅用于强调效果):div with opacity。现在,如果我移除中间 div 的不透明度:opacity disabled。突然之间,浮动的 div 可以访问了。
我尝试了 z-index 属性,但当它没有帮助时并不惊讶。我甚至在 JS fiddle 中成功复制了这个问题。
那么,这是怎么回事?有什么解决方法吗? 注意:到目前为止,在 Chrome 和 Firefox 中测试过。结果相同。Opera 也确认了。 PS.:有人能解释一下,为什么 JSFiddle 的全屏结果不能正常工作吗?我认为这不是我第一次遇到无法正常使用全屏结果。

你读完问题了吗?在发布问题之前,我已经在jsFiddle上测试过了。当然,我也添加了链接。 - Tomáš Zato
这是更新后的链接,包含更好的示例(我也在问题中进行了更新)。http://jsfiddle.net/Darker/K2nmL/1/ - Tomáš Zato
2
这个看起来很相关:https://dev59.com/VXE85IYBdhLWcg3wUByz - Turnip
2个回答

2
问题在于理解堆叠上下文以及它们在浏览器中的渲染方式。
  • 根元素(HTML),
  • 具有z-index值而被定位(绝对或相对)的元素,
  • 透明度小于1的元素。
  • 在移动端WebKit和Chrome 22+中,即使z-index为“auto”,position:fixed始终创建一个新的堆叠上下文。

9.9.1指定堆叠级别:'z-index'属性

  1. 形成堆叠上下文的元素的背景和边框。
  2. 具有负堆叠级别的子堆叠上下文(最负优先)。
  3. 非行内级别、非定位后代的流动元素。
  4. 非定位浮动元素。
  5. 包括行内表格和行内块的流动、行内级别、非定位后代。
  6. 具有堆叠级别0的子堆叠上下文和具有堆叠级别0的定位后代。
  7. 具有正堆叠级别的子堆叠上下文(最小正优先)。

当您对div应用不透明度更改时,它会创建一个新的堆叠上下文。这意味着它会创建一个新的堆叠上下文,稍后渲染(即:在具有较低级别的堆栈之上)。

根据您想要实现的效果,有不同的解决方案,以下是一个示例,演示如何通过使用rgba值而完全避免不透明度问题。

我强烈建议重新构造HTML/CSS以获得您想要的效果。

这只是一个示例,以说明问题。

http://jsfiddle.net/K2nmL/7/

CSS

#allOptions.disabled {
  cursor: default !important;
  background-color: rgba(255,0,0,0.5);
  color: rgba(0,0,0,0.5);
}

#allOptions {
    background-color: red;
}

JavaScript

// Added a function to toggle the `disabled` class

更新

一个简单的解决方案是将不透明度更改应用于包装器 div。我添加了一个包含 clearfix 的 div 来包装包装器。这仍然保持了您的布局相同,但它使所有元素都在相同的堆叠上下文中。

http://jsfiddle.net/K2nmL/8/


你的想法很好,只改变背景颜色和颜色,但是这并不适用于像图片、按钮(你可以在 fiddle 中看到一个)和其他东西。我在我的 Web 应用程序中全局使用 .disabled 类来呈现某些内容为禁用状态。除了将 opacity 设置为浮动 div 之外,是否还有其他解决方法? - Tomáš Zato
看我的更新。如果你真的想让按钮和输入框不可响应,它们都支持disabled属性。以下是一些示例:http://jsfiddle.net/a92Fu/ - thgaskell
这里变得复杂了...图片怎么办?难道真的没有解决我的问题并保持div透明的方法吗? 当我点赞你的答案时,我已经认为我有了一个解决方案,所以我没有向你询问实际适合我的解决方法。 然而,将浮动div的不透明度设置为透明也没有帮助,这是我计划的技巧。现在我真的迷失了,没有任何想法。 - Tomáš Zato
你看到我的更新了吗?如果你把 #wrapper div 放在一个新的 div 中,那么你就不会再有这个问题了,因为所有的元素都在同一个堆叠上下文中。 - thgaskell
你真的很善良,而且你有好主意。但是这里又出现了一个问题:浮动 div 绝不能不透明。我尝试了你的解决方案,使用了 0.99 不透明度(我的技巧),但是浏览器在应用之前会四舍五入,所以这并没有帮助。 - Tomáš Zato

0

你只清除了浮动的左侧,所以 #wrapper 会有0高度问题。我添加了一个clearfix类:

.clear:after {
    content: "";
    display: table;
    clear: both;
}

看一下

另外,你需要在开头使用那些<br>吗?最好通过填充/边距来实现相同的效果。 enter image description here


你的修复破坏了布局。我想要的是原始的布局... https://www.diigo.com/item/image/3wnu6/bjrx - Tomáš Zato
我看到的和我的例子一样。需要截图吗? - Mihey Egoroff
我知道你也看到了同样的事情。但是,我们所看到的不是我想要的... :( - Tomáš Zato

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