【问题标题】:CSS: position:fixed inside of position:absoluteCSS:位置:固定在位置:绝对内部
【发布时间】:2021-06-21 20:39:48
【问题描述】:

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

我有一个相当复杂的布局,但主要问题在这里:

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

#drop 有 position:absolute 和 z-index:100
#header 有 position: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 beta,它对他来说可以正常工作。我已经在 Firefox 上对其进行了测试,它有点工作(有其他症状)

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

编辑

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

编辑

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

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

【问题讨论】:

  • 您是否正在为您的固定元素设置位置值?即上:0;左:0; ?
  • 是的,很抱歉没有提到它。我有top:60px; 固定。将更新 OP。
  • 我没遇到过这个问题,也无法重现..jsfiddle.net/be53j
  • 除了我的特定示例之外也无法重现它,并注意到了错误依赖性。立即更新 OP。
  • 您是否在代码中使用 css 转换?因为如果您是 - 那就是导致 position:fixed 不起作用的原因。

标签: google-chrome css webkit openlayers


【解决方案1】:

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

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

查看规范:The Transform Rendering Model

为“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>

【讨论】:

  • 你刚刚把我从可能的最糟糕的噩梦中救了出来 :),我正在使用引导词缀并且还在父容器上使用变换,我将摆脱变换并使用 jquery animate :)
  • 谢谢,只是想补充一点,即使will-change:transform 也会触发这种行为(在最新的 chrome 中)
【解决方案2】:

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

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

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

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

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

据我所知,唯一的解决方案是将 will-change 元素的 child 改为 sibling,以防止属性级联。

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

【讨论】:

    【解决方案3】:

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

    几天前我也遇到过类似的问题。例如,如果您将 z-index 设置为 header,它将获得父级 dropcontainer 的 z-index。header 的 z-index 将没用,因为它已经在一个有另一个 z-index 的容器中。

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

    【讨论】:

    • 这有点道理,但如果它像你说的那样准确,那么 OpenLayers 就不会对此产生任何影响。如果我删除 OpenLayers(在所有 div 之外),那么我的 header 开始按预期工作。
    【解决方案4】:

    我想添加另一个可能的解决方案,因为我一直在为 chrome 忽略位置而苦苦挣扎:修复了很长一段时间,直到我终于找到了罪魁祸首:

    -webkit-perspective: 1000;
    

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

    【讨论】:

      【解决方案5】:

      我认为这是不可能的,我不认为如果两个位置可以放在同一个地方而没有一个倒塌。但我认为在javascript中使用Avail高度更好,我的意思是如果你想要一个外部div来容纳内部div,并且外部div必须覆盖整个屏幕,在js中使用Availheight,这将获得屏幕高度然后应用如果,此后将所有 div 设置在固定位置。

      【讨论】:

        【解决方案6】:

        将此添加到父级:

        position: fixed;
        

        ...这是给孩子的:

        position: sticky;
        

        【讨论】:

          【解决方案7】:

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

          我想在您的 divs 中进行一个小改动,以便将 fixed div 从 absolute 中拉出,或者将 absolute div 移到其他位置。

          【讨论】:

          • 在 OP 中我只展示了 DOM,而不是内容。每个 div 中都有子标签和文本。 fixed 不需要参考点。所有规范都声明它引用了浏览器窗口。下次请求更多信息时,请使用 cmets 而不是答案。
          猜你喜欢
          • 2021-04-27
          • 1970-01-01
          • 2013-06-08
          • 1970-01-01
          • 2014-07-01
          • 2021-09-03
          • 2011-06-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多