168

我正在使用 -webkit-transform(和 -moz-transform / -o-transform)来旋转 div。还添加了固定位置,以便 div 与用户一起向下滚动。

在 Firefox 中它工作得很好,但在基于 webkit 的浏览器中它就坏了。使用 -webkit-transform 后,固定位置不再起作用!这怎么可能?

4

17 回答 17

113

CSS 转换规范解释了这种行为。带有变换的元素充当固定位置后代的包含块,因此 position:fixed 在带有变换的东西下不再具有固定的行为。

它们在应用于同一元素时确实有效;元素将被定位为固定,然后转换。

于 2016-06-21T20:16:28.070 回答
94

经过一番研究,Chromium网站上有一个关于这个问题的bug 报告,目前 Webkit 浏览器无法同时渲染这两种效果。

我建议在您的样式表中添加一些仅 Webkit 的 CSS,并使转换后的 div 成为图像并将其用作背景。

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

所以现在你必须用老式的方式来做,直到 Webkit 浏览器赶上 FF。

编辑:截至 2012 年 10 月 24 日,该错误尚未解决。


这似乎不是一个错误,而是规范的一个方面,因为这两种效果需要单独的坐标系和堆叠顺序。如本答案所述

于 2010-04-14T12:25:12.003 回答
9

对我有用的东西(有点老套)是position:sticky

.fixed {
     position: sticky;
}
于 2013-07-21T15:02:49.110 回答
7

对于任何发现背景图像在 Chrome 中消失的人,因为背景附件存在相同的问题:已修复;- 这是我的解决方案:

// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    // set background-attachment back to the default of 'scroll'
    $('.imagebg').css('background-attachment', 'scroll');

    // move the background-position according to the div's y position
    $(window).scroll(function(){

        scrollTop = $(window).scrollTop();
        photoTop = $('.imagebg').offset().top;
        distance = (photoTop - scrollTop);
        $('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');

    });
}  
于 2014-01-13T23:43:22.100 回答
7

2016 年 8 月,固定位置和动画/变换仍然是一个问题。唯一对我有用的解决方案是为需要较长时间的子元素创建动画。

于 2016-08-16T19:45:16.867 回答
3

其实我找到了另一种方法来修复这个“错误”:

我有容器元素,其中包含带有 css3 动画的页面。当页面完成动画时,css3属性有值:transform: translate(0,0);。所以,我刚刚删除了这一行,一切都按原样工作 - position: fixed 正确显示。当应用 css 类来翻译页面时,添加了 translate 属性并且 css3 动画也可以正常工作。

例子:

.page {
     top: 50px;
     position: absolute;
     transition: ease 0.6s all;
     /* -webkit-transform: translate(0, 0); */
     /* transform: translate(0,0); */
 }
 .page.hide {
     -webkit-transform: translate(100%, 0);
     transform: translate(-100%, 0);    
 }

演示:http: //jsfiddle.net/ZWcD9/

于 2014-07-17T15:55:14.183 回答
2

我在尝试使用 react-swipeable-views (rsw) 实现 react-color 时遇到了这个问题。对我来说,问题是 rsw 适用translate(-100%, 0)于一个选项卡面板,它破坏了在全屏上添加的默认固定位置 div,单击该选项卡会关闭颜色选择器模型。

对我来说,解决方案是将相反的变换应用于固定元素(在这种情况下translate(100%, 0)解决了我的问题。我不确定这在其他情况下是否有用,但我认为无论如何我都会分享。

这是一个示例,显示了我上面描述的内容:

https://codepen.io/relativemc/pen/VwweEez

于 2019-10-13T16:24:04.890 回答
1

在我的 phonegap 项目中,webkit 转换 -webkit-transform: translateZ(0); 像魅力一样工作。它已经在 chrome 和 safari 中运行,而不是移动浏览器。还有一个问题是 WRAPPER DIV 在某些情况下没有完成。我们在浮动 DIV 的情况下应用 clear 类。

<div class="Clear"></div> .Clear, .Clearfix{clear:both;}
于 2013-04-07T04:29:23.957 回答
1

可能是由于 Chrome 中的错误,因为我无法在 Safari 或 Firefox 中复制,但这适用于 Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

这是一个非常特殊的结构,因此它绝不是一个普遍适用的单行 css 修复程序,但也许有人可以修改它以使其在 Safari 和 Firefox 中工作。

于 2015-02-13T14:05:49.460 回答
0

添加-webkit-transform到固定元素为我解决了这个问题。

.fixed_element {
   -webkit-transform: translateZ(0);
   position: fixed;
   ....
} 
于 2013-03-06T15:23:00.103 回答
0

这是适用于所有经过测试的浏览器和移动设备(Chrome、IE、Firefox、Safari、iPad、iphone 5 和 6、Android)的方法。

img.ui-li-thumb {
    position: absolute;
    left: 1px;
    top: 50%;

    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}
于 2015-05-14T17:57:38.053 回答
0

如果将变换应用于任何祖先,元素的固定位置就会被破坏。

<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok

<div style='-.*-transform:scale(2)'>
      <div style='position:fixed'>...</div> // broken
</div>
于 2015-06-23T09:17:12.850 回答
0

如果您可以使用 javascript 作为选项,这可以是一种解决方法,用于在转换元素内部时将位置固定元素相对于窗口定位:

  let fixedEl // some node that you is position 
              // fixed inside of an element that has a transform

  const rect = fixedEl.getBoundingClientRect()
  const distanceFromWindowTop = rect.top
  const distanceFromWindwoLeft = rect.left
  let top = fixedEl.offsetTop
  let left = fixedEl.offsetLeft

  if(distanceFromWindowTop !== relativeTop) {
    top = -distanceFromWindowTop
    fixedEl.style.top = `${top}px`
  }

  if(distanceFromWindowLeft !== relativeLeft) {
    left = -distanceFromWindowLeft
    fixedEl.style.left = `${left}px`
  }

当然,您还必须调整您的高度和宽度,因为fixedEl将根据它的容器计算它。这取决于您的用例,但这将允许您以可预测的方式设置固定位置,而不管它是容器。

于 2017-08-11T01:34:37.960 回答
0

在元素转换时添加一个动态类。$('#elementId').addClass('transformed'). 然后继续在css中声明,

.translatX(@x) { 
     -webkit-transform: translateX(@X); 
             transform: translateX(@x);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

然后

#elementId { 
      -webkit-transform: none; 
              transform: none;
}

然后

.transformed {
    #elementId { 
        .translateX(@neededValue);
    }
}

现在 position: fixed 当在子元素上提供 top 和 z-index 属性值时,它可以正常工作并保持固定,直到父元素转换​​。当转换被恢复时,子元素会再次以固定方式弹出。如果您实际上使用的是在单击时切换打开和关闭的导航侧边栏,并且您有一个标签集,当您向下滚动页面时应该保持粘性,这应该可以缓解这种情况。

于 2018-07-31T15:32:31.620 回答
0

在我的例子中,我发现我们不能在 transform:translateY() 之前使用 transform: translateX()。如果我们想同时使用两者,我们应该使用 transform:translate( , )。

于 2020-02-15T10:39:49.970 回答
0

如果您将动画返回到所有翻译所在的原始位置,则0可以在您设置的位置使用此解决方案transform: unset;

  100% {
    opacity: 1;
    visibility: visible;
    /* Use unset to allow fixed elements instead of translate3d(0, 0, 0) */
    transform: unset;
  }
于 2020-10-08T08:52:18.600 回答
-1

请不要投票,因为这不是确切的答案,但可以帮助某人,因为这是关闭转换的快速方法。如果您真的不需要对父级进行转换并且希望您的固定位置再次工作:

#element_with_transform {
  -webkit-transform: none;
  transform: none;
}
于 2017-08-08T14:05:15.940 回答