页面滚动时 CSS3 动画打破固定定位

Posted

技术标签:

【中文标题】页面滚动时 CSS3 动画打破固定定位【英文标题】:CSS3 animations breaking fixed positioning when page scrolled 【发布时间】:2012-07-18 19:13:49 【问题描述】:

我在试图弄清楚为什么 chrome 时遇到了麻烦(这使得固定标题完全消失,Firefox 将它保留在那里但让绝对定位的元素流过固定元素,我已经使用 opacity:.99 避免了这个问题,但我仍然在想如何解决它。

http://www.rickpascua.cu.cc/newsite-snazzy/index.html

【问题讨论】:

这个页面上没有其他东西对我有用,但是将元素的不透明度设置为 0.99 像魔术一样解决了我的问题。谢谢。 【参考方案1】:

将跟随CSS设置为消失元素

-webkit-transform: translate3d(0, 0, 0);
transform        : translate3d(0, 0, 0);

transform 属性 translated3d 不存在。 translate3d 可以,并且应该在同一页面上使用动画元素解决固定定位问题。

【讨论】:

我相信这是因为 translate3d 是硬件加速属性;我相信任何硬件加速的属性都会“解决”这个问题。有关详细信息,请参阅我的答案。【参考方案2】:

编辑:用户@jacob 指出这是一种错误的方法,可能会对性能产生负面影响。任何强制硬件加速的属性都可以解决问题,但不要全局应用此规则,而是尝试将此规则应用于仅破坏的元素。

刚刚在结合 animate.css 和 zurb 的基础时遇到了类似的问题。

我根据 Ryan Wu 的回答提出的解决方案

* 
backface-visibility: hidden;

它解决了我的问题(固定元素在动画过程中丢失填充/边框和其他讨厌的东西)

【讨论】:

谢谢!这正是我需要修复一个奇怪的 Chrome (webkit) 错误 :-) @kipusoep 最好只在您需要的元素上设置它。我在一些动画中遇到了这种方法的问题。 我相信这是因为背面可见性是硬件加速属性;我相信任何硬件加速的属性都会“解决”这个问题。有关详细信息,请参阅我的答案。 另外,请注意:在每个元素上强制硬件加速〜会〜会对性能产生负面影响,尤其是在移动设备上。 @jacob 你是 100% 正确的。它也可能导致其他错误。我可能应该删除这个答案。【参考方案3】:

我仍然不知道为什么 CSS 动画会破坏布局。在我的测试中,随着动画的运行,标题上的overflow:hidden;z-index 会导致它失去固定的定位!不过,我确实有答案。

首先,删除

overflow:hidden;
visibility:visible;
z-index:99;

来自固定位置的标题元素<div id="header">

但是,删除这 3 个属性后,<div id="slide-contain"/> 仍然会重叠!这是因为隐式堆叠上下文分层,请参阅CSS_absolute_and_fixed_positioning#The_third_dimension 文章中的 7 层。

出现不需要的重叠是因为position:relative 已在<div id="slide-contain"/>(它是<div id="wrapper"/> 的后代)上设置,但该元素上没有z-index。我意识到添加了相对定位是因为您想在其中绝对定位一些子元素。

因此,<div id="slide-contain"/> 元素与页面上没有 z-index 的所有其他元素位于同一 Z 平面上,其中包括固定标题。根据链接的文章,这两个元素都处于第 6 级 - 将堆栈级别设置为自动或(零) 的定位后代,并且堆栈默认为元素在 DOM 上出现的顺序,所以 <div id="slide-contain"/> 被渲染在 `.

因此,标题上需要z-index:1 以始终将标题呈现在顶部。它只需要大于0,所以将z-index:99更改为z-index:1

另一种解决方案是为以下兄弟<div id="wrapper"/> 提供否定 z-index(和position:relative)。

您可能认为在<div id="slide-contain"/> 上添加一个负数z-index 就足够了,但它需要复制到元素祖先,否则<div id="slide-contain"/> 将被推到其父元素后面。

【讨论】:

啊,非常感谢,回想起来,我不会在绝对位置元素上尝试 z-index 似乎有点愚蠢,我认为我的固定元素上的单个 z-index 总是覆盖它学习! 很高兴为您提供帮助 :-) 我实际上仍在尝试为这个问题创建一个简单的测试用例,因为我也对动画为什么会破坏布局感到困惑。【参考方案4】:

我相信这个错误的发生是因为容器的动画被卸载到了 GPU;但是,固定定位会将后代从流中取出,因此它不会与容器一起卸载。然后错误地合成了固定位置元素。将任何硬件加速属性(例如translate3d)添加到固定位置的元素似乎可以“解决”问题(我相信因为它随后也会被卸载到 GPU,从而避免了合成过程中的问题)。

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

.container 
  animation-duration: 0.8s;
  animation-name: some-animation;


.fixed 
  /* transform: translateX(-200%); */
  transform: translate3d(-200%, 0, 0);
  position: fixed;
  top: 10rem;

【讨论】:

【参考方案5】:
background: url(../assets/logo.png) center no-repeat,url(../assets/header2.jpg) bottom center;
height: 50px;
width: 100%;
border-bottom: 5px solid black;
position: fixed;
text-align: center;
z-index: 99;

试试这个吧。

但是你在标题 div 中的内部 html 也存在问题,你使用的是浮动 div,所以如果你想使用溢出:隐藏或自动,你也应该使用 clear 类。

【讨论】:

我有一个指定的高度所以真的不需要清除修复和溢出:隐藏是因为动画有溢出但不可见的边缘。我尝试了代码,但问题仍然存在。

以上是关于页面滚动时 CSS3 动画打破固定定位的主要内容,如果未能解决你的问题,请参考以下文章

求助:如果使用js\jq 控制一个div 当滚动到页面顶部的时候固定在顶部,离开可继续滚动

vue项目中滚动时导航吸顶效果(固定定位)

怎么用js固定某个元素,让它不随页面的滚动而滚动,始终固定在窗口的某个位置?

固定定位破坏 z-index

当元素从相对位置定位到固定位置但腾出的空间保持固定高度时,是不是会发生页面重排

如何在不将页面滚动条重置为顶部的情况下使用 jQuery 为固定 div 设置动画