CSS:由于不透明度,悬停无法正常工作

16

我遇到了一个奇怪的CSS问题。

以下是一个非常简单的代码示例,演示了这个问题。

<html>
  <head>
     <style>
      .hover {
        float: right;
      }
      .hover:hover {
        background-color: blue;
      }
      .blocker {
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
    <div class="hover">hover</div>
    <div class="blocker">blocker</div>
  </body>
</html>

我有一个浮动在另一个div上方的div A,后者的不透明度为0.5。我想在浮动的div上添加CSS悬停规则,但出现了问题。

无论我向右还是向左浮动,都没用。

但是当我将不透明度改为1时,悬停规则突然起作用了。

有人能解释这种行为吗?

我可以通过将封锁div的内容包装在span中来“修复”问题,但感觉不应该这么做。

这里有一个 jsFiddle,演示了这个问题:http://jsfiddle.net/ed82z/1/


5
以下回答似乎都没有解释为什么将不透明度设置为1可以起作用,而0.5却不行。 - Denys Séguret
这会给你一个提示:http://jsfiddle.net/abhitalks/ed82z/4/ - Abhitalks
2
层叠上下文:(请参见此处) “在文档中的任何位置,只要元素满足以下条件之一,就会形成一个层叠上下文:...不透明度小于1的元素”。 - Abhitalks
1
这个链接很有趣,但在我看来远远不够精确来解释这里发生的事情。 - Denys Séguret
@dystroy:是的。这就是为什么只是一个评论而不是一个尝试回答的原因。 - Abhitalks
3个回答

20

简单地说,如果不透明度小于1,则它位于“上方”。

关键术语是层叠上下文

通过将不透明度设置为小于1的值,根据规范,它会以不同的方式进行分层,因为它接收到一个新的层叠上下文并位于元素下面。

它在此处浮动不透明度中指定:

根元素形成了根层叠上下文。其他层叠上下文由任何具有计算的“z-index”值而不是“自动”的定位元素(包括相对定位的元素)生成。层叠上下文不一定与包含块相关。在CSS的未来级别中,其他属性可能会引入层叠上下文,例如“不透明度”[CSS3COLOR]。

从不透明度中:

由于不透明度小于1的元素是从单个离屏图像合成的,因此它外部的内容不能在其中的内容片段之间以z-order进行分层。由于同样的原因,实现必须为任何不透明度小于1的元素创建新的层叠上下文。如果不透明度小于1的元素未定位,则实现必须在其父层叠上下文中绘制其创建的图层,并按照与其“z-index:0”和“opacity:1”的定位元素相同的堆叠顺序。如果不透明度小于1的元素被定位,则“z-index”属性的应用方式如[CSS21]所述,除了将“auto”视为“0”,因为始终创建了一个新的层叠上下文。有关层叠上下文的更多信息,请参见[CSS21]的第9.9节和附录E。本段规则不适用于SVG元素,因为SVG具有自己的呈现模型([SVG11],第3章)。

如何修复:

您可以将pointer-events设置为none,请参见这个fiddle


除非您将z-index设置为负值,否则它在上方。 - John Dvorak
浮动元素的内容会像生成新的堆叠上下文一样被堆叠,但是任何定位元素和实际创建新的堆叠上下文的元素都参与浮动元素的父级堆叠上下文。浮动元素可以重叠在正常流中的其他盒子上(例如,当浮动元素旁边的正常流盒子具有负边距时)。当发生这种情况时,浮动元素会呈现在非定位内联块的前面,但在内联块后面。 - Benjamin Gruenbaum
@JanDvorak 是的,你可以使用z-index来“解决”这个问题:http://jsfiddle.net/webtiki/ed82z/6/ - web-tiki
1
令我困扰的是,你无法通过设置明确的 z-index 来修复它。 - Denys Séguret
1
@dystroy 我认为这句话并不意味着设置明确的 z-index 就可以解决问题,因为 z-index 不适用于非定位元素。 - James Montagne
显示剩余7条评论

4

对我来说,添加overflow: hidden解决了问题:

.blocker {
    opacity: 0.5;
    overflow:hidden;
}

或者:

.blocker { 
        opacity: 0.5;
        position:relative; 
        z-index:-1;
}

(感谢 @Eyal Barta 提供此选项)

http://jsfiddle.net/ed82z/7/

原因在于 .blocker 遮盖了其它 div,可以使用 firebug 或其他开发工具轻松查看。

当你添加不透明度时,你就会添加一个“层叠上下文”。

这是因为这些 DIV 具有特殊的属性,使它们形成一个层叠上下文。

在本例中:透明度小于 1 的元素。 这会给你的 div 添加一个 z-index,导致其以不同的顺序呈现。

层叠上下文详解


3
为什么将不透明度设置为1会修复它? - Denys Séguret
不错,我不知道这个..所以添加{ position:relative; z-index:-1;}也应该解决这个问题.. - webkit

0
在代码中,由于使用了 float:right;.blocker 类与 .hover 类发生了重叠。
.blocker {
    opacity: 0.5; 
    width:100px
}

你可以在 blocker 类中修复这个 float:left,或者为 div 设置 width:100px 的固定宽度,这样它就不会重叠了。


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