绝对定位的元素相对于变换元素的位置

时间:2016-04-21 19:47:34

标签: css css3 css-position transform css-transforms

我重新创建了一个我在模板中遇到的问题。 导航position: relative;。在导航内,有一个 div ,其中嵌套了两个列表 其中一个列表绝对是坚持导航的底部。 当 div 应用了转换时,会出现此问题 当绝对和相对定位元素之间的 div 获得变换属性时,绝对列表相对于 div 而不是 nav < /强>

MDN Docs state the following about position:absolute

  

不要为元素留出空间。相反,将它定位在   相对于其最近定位的祖先的指定位置(如果有的话),   或相对于包含块。绝对定位   盒子可以有边距,并且它们不会与任何其他盒子一起崩溃   边距。

这是否意味着转换元素是定位元素? 为什么这样做?我在Edge,FF和Chrome中测试过。它们都是一样的。

您可以在下面运行重新创建的代码段。我正在使用导航悬停时对div进行转换。

&#13;
&#13;
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html, body{
  min-height: 100%;
  height: 100%;
}
nav{
  background: #000;
  height: 100%;
  width: 50%;
  position: relative;
}
nav:hover > div{
      transform: translateX(50px) translateY(0) translateZ(0);
}
a{
  color: #fff;
}
ul{
  padding: 16px;
}
ul.main{
  background: blue;
}

ul.lower{
  position: absolute;
  background: red;
  bottom: 0;
  width: 100%;
}
&#13;
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<nav>
  <div>
    <ul class="main">
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
    </ul>
    <ul class="lower">
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
      <li><a href="">link</a></li>
    </ul>
  </div>
</nav>
</body>
</html>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:4)

CSS规范指出defining a transform on an element creates a containing block

  

对于布局由CSS框模型控制的元素,转换的除none之外的任何值都会导致创建堆叠上下文和包含块。

那(see spec):

  

在绝对定位模型中,框相对于其包含块显式偏移。



这里的关键是将元素的transform属性设置为none以外的任何属性,创建一个新的包含块; 堆叠上下文与元素的放置方式无关。

请参阅以下代码段中的示例。

&#13;
&#13;
body {
  padding-top: 100px;  
}

.containing-block,
.stacking-context {
  height: 50px;
  padding-top: 50px;
}

.containing-block {
  background-color: hotpink;
  /* transform with a value other than none defines both a containing block and a stacking context. */ 
  transform: scale(1);
}

.stacking-context {
  background-color: orange;
  /* opacity with a value other than 1 defines a stacking context but no containing block. */
  opacity: .99;
}

.abs{
  position: absolute;
  top: 0;
    
  padding: 10px;

  background-color: dodgerblue;
}
&#13;
<body>
  <div class="containing-block">1: transform: scale(1);
    <div class="abs">1: Containing block example</div>
  </div>

  <div class="stacking-context">2: opacity: .99
    <div class="abs">2: Stacking context example</div>
  </div>
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果您将转换应用于.main而不是div,它似乎可以按预期工作。

答案 2 :(得分:-1)

基本上因为应用了transform属性的任何元素会自动触发新的堆叠顺序:https://developer.mozilla.org/en-US/docs/Web/CSS/transform

&#34;如果属性的值不是none,则将创建堆叠上下文。在这种情况下,对象将充当位置的包含块:它包含的固定元素。&#34;

以下是有关堆叠上下文的一些额外信息:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context