CSS: position:fixed inside position:absolute

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15152712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:50:32  来源:igfitidea点击:

CSS: position:fixed inside of position:absolute

google-chromecsswebkitopenlayers

提问by Mikhail

I'm running into some extremely strange behaviors, and non-consistant across every browser i've tested.

我遇到了一些非常奇怪的行为,并且在我测试过的每个浏览器中都不一致。

I've a pretty complex layout, but the main issue lies here:

我有一个非常复杂的布局,但主要问题在于:

<div id="drop">
  <div id="header"></div>
</div>

#drophas position:absoluteand z-index:100
#headerhas position:fixed; top:60px;

#dropposition:absolutez-index:100
#headerposition:fixed; top:60px;

As I start scrolling down Chrome ignores the position:fixedrule. If I remove eitherof the two styles above from #dropthen Chrome starts respecting the position:fixedrule.

当我开始向下滚动时,Chrome 忽略了该position:fixed规则。如果我从中删除上述两种样式中的任何一种#dropChrome 就会开始position:fixed遵守规则。

can't get it working on Ubuntu Chrome 23.0.1271.97 and see the same behavior on Mac Chrome 25.0.1364.99. My friend uses Ubuntu Chrome 25.0.1364.68 beta and it works correctly for him. I've tested it on firefox and it kinda works (with other symptoms)

无法在 Ubuntu Chrome 23.0.1271.97 上运行,并在 Mac Chrome 25.0.1364.99 上看到相同的行为。我的朋友使用 Ubuntu Chrome 25.0.1364.68 beta,它对他来说工作正常。我已经在 Firefox 上测试过它,它有点工作(有其他症状)

Has anyone heard of this error? or can anyone even reproduce it?

有没有人听说过这个错误?或者任何人都可以复制它?

edit

编辑

I'm using openlayers map as another div with position:fixedif I delete that layer or at least change it to display:nonethen this weird bug goes away.

我正在使用 openlayers 地图作为另一个 div,position:fixed如果我删除该图层或至少将其更改为display:none那么这个奇怪的错误就会消失。

edit

编辑

Noticed that during the presence of this bug, if I change the zoom level back and forth, then the position adjusts itself to the proper behavior. To me, this indicates a webkit issue that fails to execute some internal callback function on scroll.

请注意,在出现此错误期间,如果我来回更改缩放级别,则位置会自行调整为正确的行为。对我来说,这表明 webkit 问题无法在滚动时执行某些内部回调函数。

Another extremely strange thing is that I have a few links inside of #headerand they work if I just click the expected location, even though the the div does not appear there. Overall I've noticed that it's only the renderingthat's broken. If at any point of time I force the browser to re-render by resizing the window, or changing zoom, or just doing Select-All, then the header bar jumps to the proper position, but does not remain fixed.

另一个非常奇怪的事情是,我在里面有一些链接,#header如果我只是单击预期的位置,它们就可以工作,即使 div 没有出现在那里。总的来说,我注意到只有渲染被破坏了。如果在任何时候我通过调整窗口大小、更改缩放比例或仅执行 Select-All 来强制浏览器重新呈现,则标题栏会跳转到正确的位置,但不会保持固定。

回答by Danield

You mentioned in the comments that OpenLayers uses CSS transforms. That being the case:

您在评论中提到 OpenLayers 使用 CSS 转换。既然如此:

the element with fixed positioning will become relative to the element with the transform - not relative to the viewport

具有固定定位的元素将相对于具有变换的元素 -而不是相对于视口

Take a look at the spec: The Transform Rendering Model

看一下规范:变换渲染模型

Specifying a value other than ‘none' for the ‘transform' property establishes a new local coordinate system at the element that it is applied to.

.wpr
{
    width: 200px;
    height:1000px;
    background: pink;
    position:relative;
    margin: 0 200px;
    -webkit-transform: translateX(0);
    transform: translateX(0);
}
.fixed
{
    width: 200px;
    height:200px;
    margin: 50px;
    position: fixed;    
    top:0;
    left:0;
    background: aqua;
}
<div class="wpr">
    <div class="fixed"></div>
</div>

为 'transform' 属性指定一个非 'none' 的值会在应用它的元素上建立一个新的局部坐标系。

.wpr
{
    width: 200px;
    height:1000px;
    background: pink;
    position:relative;
    margin: 0 200px;
    -webkit-transform: translateX(0);
    transform: translateX(0);
}
.fixed
{
    width: 200px;
    height:200px;
    margin: 50px;
    position: fixed;    
    top:0;
    left:0;
    background: aqua;
}
<div class="wpr">
    <div class="fixed"></div>
</div>

回答by forresthopkinsa

As the accepted answer says, this is the intended behavior, and is spec-compliant. Another important component of this is what it means to be using CSS transforms.

正如接受的答案所说,这是预期的行为,并且符合规范。另一个重要的组成部分是使用 CSS 转换意味着什么。

In your case, it was due to OpenLayers, but this applies to anyone using will-change: transformas well (probably a lot of the people visiting this question). This has been brought up on the Chromium bug tracker here, and marked as WontFix, because (as I said) it's intended behavior. The official comment is this:

在您的情况下,这是由于 OpenLayers,但这也适用于任何使用will-change: transform它的人(可能很多访问此问题的人)。这已在此处的 Chromium 错误跟踪器上提出,并标记为WontFix,因为(正如我所说)这是预期的行为。官方评论是这样的:

This behavior is required by the spec (http://dev.w3.org/csswg/css-will-change/): "If any non-initial value of a property would cause the element to generate a containing block for fixed-position elements, specifying that property in will-change must cause the element to generate a containing block for fixed-position elements."

The idea is that once will-change:transform is specified, you should be able to add/remove/change transforms cheaply, without needing fixed-position descendants to get re-layed-out.

Note that using other values of will-change (e.g. opacity, top) will not change the positioning of fixed-position descendants.

规范 ( http://dev.w3.org/csswg/css-will-change/)要求此行为:“如果属性的任何非初始值会导致元素为固定的生成包含块-位置元素,在 will-change 中指定该属性必须使元素为固定位置元素生成一个包含块。”

这个想法是,一旦指定了 will-change:transform,您应该能够廉价地添加/删除/更改转换,而无需固定位置的后代重新布局。

请注意,使用 will-change 的其他值(例如 opacity、top)不会改变固定位置后代的定位。

As far as I am aware, the only solution is to make the childof the will-changeelement a siblinginstead, to prevent the attribute from cascading.

据我所知,唯一的解决办法是让孩子在的will-change元素的兄弟姐妹代替,防止属性的级联。

As a side note, in my specific case, I was able to fix it by being more specific with the will-changeattribute. Instead of using it on the divcontaining the performance-jarring element that required GPU offloading, I used it directly on the offending element. This was due to my original bad code, though, so it won't work for most cases.

作为旁注,在我的特定情况下,我能够通过更具体的will-change属性来修复它。我没有在div包含需要 GPU 卸载的性能不稳定元素上使用它,而是直接在有问题的元素上使用它。不过,这是由于我原来的错误代码造成的,所以它在大多数情况下都不起作用。

回答by Rahul Shah

You will have to place headeroutside the parent container dropto make it work.

您必须将其放置header在父容器之外drop才能使其工作。

I had slightly similar issues days back.For instance,if you set z-index of header,it will be attain the z-index of the parent dropcontainer.The z-index of headerwill be useless because it is already inside a container which has another z-index.

几天前我遇到了一些类似的问题。例如,如果您将 z-index 设置为header,它将获得父drop容器的 z-index。 的 z-indexheader将无用,因为它已经在一个容器中,而该容器有另一个z 指数。

The same logic of z-index applies to position.

z-index 的相同逻辑适用于位置。

回答by parliament

I want to add another possible solution because I was struggling with chrome ignoring position:fixed for quite some time until I finally found the culprit:

我想添加另一个可能的解决方案,因为我一直在努力解决 chrome 忽略 position:fixed 很长一段时间,直到我终于找到了罪魁祸首:

-webkit-perspective: 1000;

It was coming from a plugin I was using and causes ALL position:fixed elements to be ignored. Hope it helps someone.

它来自我正在使用的插件并导致 ALL position:fixed 元素被忽略。希望它可以帮助某人。

回答by Sheric

First of all, put something in your divas empty ones behave really weird. Then, what do you expect by putting a fixedinto an absolute? Obviously, nobody knows what is the reference point of your fixeddiv. Should it be its parents position? which is not changing with scroll or the page position which changes? Try to use things that are completely meaningful and have a clear definition because if you fix it in chrome, what would happen with another browser? Do you really prefer to test is on all of them?

首先,把一些东西放进你的div空的行为真的很奇怪。那么,将 afixed放入 an 中您期望什么absolute?显然,没有人知道你的fixeddiv的参考点是什么。应该是它的父母位置吗?哪个不会随着滚动或页面位置的变化而变化?尝试使用完全有意义并且有明确定义的东西,因为如果你在 chrome 中修复它,其他浏览器会发生什么?你真的更喜欢测试所有这些吗?

I suppose a small change in your divs so that pull the fixeddiv out of the absoluteone or move the absolutediv somewhere else.

我想你的divs有一个小的变化,以便将fixeddiv 拉出absolute一个或将absolutediv移动到其他地方。