如何在变换元素内保持元素的固定位置?

5

在IT技术中已知一个“bug”是如果容器被翻译,则具有固定位置的元素会失去它们的位置。例如,如果我有这样的结构:

<div class="container">
   <div class="fixed"></div>
</div>

假设容器被滚动,当容器发生变换(例如translate(x,y), rotate()等),那么固定元素的行为就像它是相对定位的,并且随着容器一起滚动。例如在最新版本的Firefox浏览器中可以看到这种情况。

有什么方法可以解决这种问题吗?

3个回答

2
这种行为不是bug,实际上是规范推荐的行为。(参见Eric Meyer的这篇文章或者这个在SO上的问题,其被接受的解决方案只提供了指向同一篇Meyer文章的链接)。
对于那些不知道这个问题的人,并且因为你没有在问题中提供代码片段,这里提供一个。

document.addEventListener('click', function() {
  document.getElementById('container').classList.toggle('transformed')
}, false);
#bg {
  border: 1px solid #AFA;
  height: 100%;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
}
#container {
  border: 1px solid #FAF;
  height: 50%;
  width: 75%;
  position: relative;
  margin: 0 auto;
  overflow: auto;
}
#content {
  background: rgba(125, 175, 0, .7);
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
}
.transformed {
  transform: translate(0, 5em);
}
<div id="bg">
  <div id="container" class="transformed">
    .<br>.<br>.<br>.<br>.<br>.<br>.
    this is a scrollable paragraph
    <br>.<br>the "fixed" content does scroll with the paragraph
    <br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
    you can click to toggle the transformation On/Off
    <br>.<br>.<br>.<br>.<br>.
    <span id="content">relatively fixed content</span>
  </div>
</div>

然而,我找到了一些可能会帮助其他人面对相同问题的东西。
这不是真正的解决方案,因为"固定"元素仅在容器内部(除了IE浏览器,在那里它将真正固定在文档中)。但在我的情况下,这实际上是我想要的,也许对其他人来说也可以。

如果您添加一个包装器,设置其height: 100%; width: 100%;overflow: auto,那么您的"固定"内容将不会随容器滚动

实际上,现在滚动的不再是您的容器,而是包装器。因此,您可能需要设置容器的overflow: visiblehidden,以避免并不是很好的“固定”元素出现意外滚动。
另外,请注意,您的包装器需要是blockinline-block元素。

#bg {
  border: 1px solid #AFA;
  height: 100%;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
}
#container {
  border: 1px solid #FAF;
  height: 50%;
  width: 75%;
  position: relative;
  margin: 0 auto;
  overflow: visible;
}
#wrapper {
  height: 100%;
  width: 100%;
  overflow: auto;
}
#content {
  background: rgba(125, 175, 0, .7);
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
}
.transformed {
  transform: translate(0, 50%);
}
<div id="bg">
  <div id="container" class="transformed">
    <div id="wrapper">
      .<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
      <span id="content">relatively fixed content</span>
    </div>
  </div>
</div>


0

我不熟悉这个错误,但当您使用 positioned: fixed; 时,元素的定位是相对于浏览器窗口的,因此将其放置在容器内没有任何意义。 以下标记是我建议采用的:

<div class="fixed"></div>
<div class="container"></div>

不总是。我的情况是一个标题栏,在容器滚动时只能滚动到一定程度,然后其中一部分被固定设置。容器也是绝对定位的。你知道的,那种事情。由于在同一页上还要构建一个离屏画布,我需要在容器上使用translate3D。 - Luca Reghellin

-1

当你在任何元素上使用position: fixed;时,它会相对于视口定位。直接来自MDN关于position属性的页面

fixed
不为该元素留出空间。相反,将其定位到屏幕视口的指定位置,并在滚动时不移动它。

所以你正在经历的是实际上应该工作的方式,而不是一个“错误”。

现在,如果你想要的是与.container div相关联并随之移动的东西,那么你将不得不在这里使用absolute定位。看一下这个fiddle。重要的CSS是-

.container {
  width: 200px;
  height: 100px;
  position: relative;
}
.absolute {
  position: absolute;
  width: 20px;
  height: 10px;
  top: 50px;
  left: 50px;
}

请注意,将内部 div 定位为 absolute 时,我还将外部 div 定位为 relative,因为内部 div 的位置是相对于最近的父 div 定位为除 static 以外的任何其他值。

嗨,谢谢你的回复,但那并不完全符合我的情况,请看我上面的评论。我知道固定元素应该保持不变,但这是一个混合元素(它会改变)。因此,我需要在[定位+滚动+翻译]元素内部放置一个固定元素,并且固定元素必须始终保持固定。 - Luca Reghellin
那么,当你说混合时,是指它应该在某些部分正常定位,而在某些部分后固定定位吗?请详细解释一下,因为一旦你在任何东西上使用 fixed,父容器的任何操作都不会起作用。 - vabhdman

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