CSS:position:fixed of position:absolute

时间:2013-03-01 07:29:42

标签: css google-chrome css3 webkit openlayers

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

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

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

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

当我开始向下滚动时,Chrome会忽略position:fixed规则。如果我从#drop移除上述两种格式的 ,那么Chrome就会开始尊重position:fixed规则。

无法在Ubuntu Chrome 23.0.1271.97上运行,并在Mac Chrome 25.0.1364.99上看到相同的行为。我的朋友使用Ubuntu Chrome 25.0.1364.68测试版,它可以正常使用。我在firefox上测试了它,它有点工作(有其他症状)

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

修改

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

修改

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

另一个非常奇怪的事情是我在#header内部有一些链接,如果我只是点击预期的位置它们就可以工作,即使div没有出现在那里。整体我注意到只有渲染才被打破。如果在任何时候我强制浏览器通过调整窗口大小,或更改缩放,或只是选择全部来重新渲染,那么标题栏会跳转到正确的位置,但不会保持固定。

7 个答案:

答案 0 :(得分:25)

您在评论中提到OpenLayers使用CSS转换。情况就是这样:

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

查看规范:The Transform Rendering Model

  

为'transform'属性指定'none'以外的值   在元素处建立一个新的局部坐标系   适用于。

在webkit浏览器中查看此FIDDLE以查看此操作

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

.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;
}

答案 1 :(得分:2)

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

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

  

规范要求此行为   (http://dev.w3.org/csswg/css-will-change/):&#34;如果有任何非初始值   属性将导致元素生成包含块   对于固定位置元素,指定该属性将改变   必须使元素为其生成包含块   固定位置元素。&#34;

     

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

     

请注意,使用其他值将会改变(例如,不透明度,顶部)   不改变固定位置后代的定位。

据我所知,唯一的解决方案是将will-change元素的改为兄弟,以防止该属性进行级联

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

答案 2 :(得分:1)

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

我几天后遇到了类似的问题。例如,如果你设置header的z-index,它将获得父drop容器的z-index。z-index of header将无用,因为它已经在具有另一个z-index的容器中。

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

答案 3 :(得分:0)

我想添加另一种可能的解决方案,因为我正在努力克服铬忽略位置:修复了很长一段时间,直到我终于找到了罪魁祸首:

-webkit-perspective: 1000;

它来自我正在使用的插件并导致所有位置:固定元素被忽略。 希望它可以帮到某人。

答案 4 :(得分:0)

我认为这是不可能的,我不认为是否可以将两个位置放置在同一位置而不会塌陷。但是我认为最好在JavaScript中使用Avail height,我的意思是,如果您想使用外部div来容纳内部div,并且外部div必须覆盖整个屏幕,请在js中使用Availheight,这将获取屏幕高度,然后在以下情况下应用然后将所有div设置在固定位置。

答案 5 :(得分:0)

将此添加到父级:

position: fixed;

...这是给孩子的:

position: sticky;

答案 6 :(得分:-5)

首先,在div中添加一些内容,因为空的内容非常奇怪。然后,通过将fixed放入absolute,您的期望是什么?显然,没有人知道你的fixed div的参考点是什么。它应该是父母的位置吗?哪个没有随滚动或页面位置的变化而改变?尝试使用完全有意义并且定义清晰的东西,因为如果你在chrome中修复它,那么另一个浏览器会发生什么?你真的更喜欢测试所有这些吗?

我想您div中的一个小变化,以便将fixed div从absolute中移出或将absolute div移到其他位置。