悬停,z-index和分层......一个令人费解的烂摊子?

时间:2016-09-25 00:08:28

标签: html css

我是一名网络开发人员,希望有更多经验的人可以提供帮助。

<type_traits>
<div id="domain-background-container">
  <div class="domain-hotspots">
    <div id="hotspot">
      <p class="bubble">I'm red on hover</p>
    </div>
  </div>
</div>

<div id="page-nav" >
  <p>I'm red on hover</p>
</div>

这是jsfiddle

问题是当鼠标光标放在它上面时,#hotspot(即绿色方块)不会进入悬停状态。

我希望解释四件事:

  1. 有人可以提供或指出我对防止#hotspot进入悬停状态的机制的详细解释吗?
  2. 删除CSS规则集(1)[html和body的高度:100%]允许#hotspot进入悬停状态。这在我的项目中不是一个可行的解决方案,但出于好奇心的利益,为什么这会产生影响。
  3. 删除CSS规则集(2)的z-index也允许#hotspot进入悬停状态。不幸的是,这也搞砸了z-ordering为.domain-hotspots(蓝色)然后覆盖#page-nav(黄色),这是不可接受的。从理论上讲,我可以定位并提高#page-nav的z值。虽然这对于这个简单的jsfiddle是有用的,但是我不愿意为一个更大的项目做这件事,我必须将它应用于跟随.domain-hotspots的每个元素(这甚至不应该是必要的,因为我的理解元素与在html文件中跟随.domain-hotspots的未修改的z-index应该在视口中的.domain-hotspots上呈现): - /
  4. 我不能使用我刚才提到的两个“解决方案”,那么还有什么解决方案呢?
  5. 我真的很感激人们可以分享的任何知识!我很难过。我甚至不确定我应该谷歌去研究这个问题,因为我不知道是什么导致了这种行为。

3 个答案:

答案 0 :(得分:5)

  1. 通过将#domain-background-container设置为z-index: -10,您实际上将该div放在body标记后面,因此您将鼠标悬停在body标记上,而不是{{1标签。
  2. 删除#hotspot&amp;上的100%高度body元素,html元素的高度实际上是body元素的高度(因为另一个元素定位为#page-nav,所以它不会占用页面的高度) - 因此 - 你可以悬停它,因为没有其他元素位于“之前” - 基于z-index。
  3. 不确定这里是否有问题(?)
  4. 您的解决方案是设置fixed#nav-page的位置,然后移除relative上的z-index
  5. 以下是一个例子:

    #domain-background-container
    html, body {
      height: 100%; 
    }
    
    #domain-background-container {
      position: fixed;
    }
    
    .domain-hotspots {
      width: 100vw;
      height: 100vh;
      position: fixed; 
      background: blue; 
    }
    
    #hotspot {
      width: 2em;
      height: 2em;
      background: green; 
    }
    
    #hotspot:hover .bubble {
      background: red; 
    }
    
    #page-nav {
      width: 100%;
      text-align: center;
      background: yellow; 
      position: relative;
    }
    
    #page-nav:hover p {
      color: red; 
    }

答案 1 :(得分:5)

  

有人可以提供或指出我对阻止#hotspot进入悬停状态的机制的详细解释吗?

<body>正在掩盖它 通过使用浏览器开发工具的“Inspect element”功能可以看出这一点 (由于z-index的工作原理,给它一个background不会将该背景放在div前面。)

  

删除CSS规则集(1)[html和body的高度:100%]允许#hotspot进入悬停状态。这在我的项目中不是一个可行的解决方案,但出于好奇心的利益,为什么这会产生影响。

使用height: 100%

screenshot

没有height: 100%

screenshot

  

[...]对我理解的元素有未修改的z-index,html文件中的.domain-hotspots应该在视口中的.domain-hotspots之上呈现。

来自CSS Level 2 draft,§9.9.1:

  

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

     
      
  1. 构成堆叠背景的元素的背景和边框。
  2.   
  3. 子堆叠上下文具有负堆栈级别(最多为负数)。
  4.   
  5. 流入的,非内联级别,未定位的后代。
  6.   
  7. 未定位的花车。
  8.   
  9. in-flow,内联级别,非定位后代,包括内联表和内联块。
  10.   
  11. 堆叠级别为0的子堆叠上下文和堆栈级别为0的已定位后代。
  12.   
  13. 具有正堆栈级别的子堆叠上下文(最少积极的第一个)。
  14.   
    由于任何#page-nav上的默认display: block
  • <div>属于类别3。
  • 由于#domain-background-container
  • position: fixed属于第2类,会将其从流中移除并创建子堆叠上下文,并且由于其为负z-index

类别3在第2类上呈现,因此#page-nav位于#domain-background-container之前 现在,当您从z-index中移除#domain-background-container或将其设为0或正数时,它将变为类别6或7,从而在#page-nav之后呈现(

  

从理论上讲,我可以定位并提高#page-nav的z值。虽然这对于这个简单的jsfiddle是有效的,但是我不愿意为一个更大的项目做这件事,我必须将它应用于跟随.domain-hotspots的每个元素。 [...]我不能使用我刚才提到的两个“解决方案”,那么还有什么解决方案呢?

你实际上不必提升它的z-value,你只需要定位它。即使是position: relative也会这样做 将其应用于#domain-background-container之后的每个元素也不是奇迹:

#domain-background-container ~ * {
    position: relative;
}

效果很好:

html, body {      /* <--- (1) */
  height: 100%; }

#domain-background-container {
  position: fixed;
  /*z-index: -10;*/ }  /* <--- (2) */

#domain-background-container ~ * {
  position: relative; }

.domain-hotspots {
  width: 100vw;
  height: 100vh;
  position: fixed; 
  background: blue; }

  #hotspot {
    width: 2em;
    height: 2em;
    background: green; }

  #hotspot:hover .bubble {
    background: red; }

#page-nav {
  width: 100%;
  text-align: center;
  background: yellow; }

#page-nav:hover p {
  color: red; }
<div id="domain-background-container">
  <div class="domain-hotspots">
    <div id="hotspot">
      <p class="bubble">I'm red on hover</p>
    </div>
  </div>
</div>

<div id="page-nav" >
  <p>I'm red on hover</p>
</div>

不可否认,在某些情况下,定位所有这些元素是不可行的。

另一个解决方案是简单地定位body元素,然后允许你给它自己的z-index

body {
    position: relative;
    z-index: -11;
}

演示:

html, body {      /* <--- (1) */
  height: 100%; }

body {
    position: relative;
    z-index: -11; }

#domain-background-container {
  position: fixed;
  z-index: -10; }  /* <--- (2) */

#domain-background-container ~ * {
  position: relative; }

.domain-hotspots {
  width: 100vw;
  height: 100vh;
  position: fixed; 
  background: blue; }

  #hotspot {
    width: 2em;
    height: 2em;
    background: green; }

  #hotspot:hover .bubble {
    background: red; }

#page-nav {
  width: 100%;
  text-align: center;
  background: yellow; }

#page-nav:hover p {
  color: red; }
<div id="domain-background-container">
  <div class="domain-hotspots">
    <div id="hotspot">
      <p class="bubble">I'm red on hover</p>
    </div>
  </div>
</div>

<div id="page-nav" >
  <p>I'm red on hover</p>
</div>

答案 2 :(得分:4)

管理这一切如何运作的规则有点复杂;如果您真的想要查看它,请参阅CSS规范中的Appendix E. Elaborate description of Stacking Contexts。至于你的具体问题:

  1. 热点未被触发,因为#domain-background-container为负z-index,因此具有默认z-index的正文覆盖了它,并且&#34;阻止&#34 34;指针事件。如果您进入开发人员工具并使用&#34;单击以选择元素&#34;您可以看到这一点。特征;身体突出显示而不是热点,因为它位于顶部。

  2. 如果你移除了身体的高度,因为身体只包含定位元素,身体的自然高度现在为0,所以它不再阻挡背景。如果你给它一个元素或者它包含&#34; flow&#34;借给它高度的元素(不是绝对的或固定的)。

  3. 是的,玩z-index游戏在项目中不能很好地扩展;保持最低限度并尽可能使用自然堆叠。

  4. 目前还不清楚您对网页布局的意图,但有多种潜在的解决方案。您可以对要使用鼠标事件的元素使用pointer-events: none来通过&#34;例如,低级别。

  5. 样品:

    body {
      pointer-events: none;
    }
    
    #domain-background-container {
      pointer-events: auto;
    }