151

我有一种情况,在正常的 CSS 情况下,一个固定的 div 将准确定位在它指定的位置(top:0px, left:0px)。

如果我有一个具有 translate3d 转换的父级,这似乎不受尊重。我没有看到什么吗?我尝试过其他 webkit-transform 样式和转换源选项,但没有运气。

我附上了一个带有示例的JSFiddle,我希望黄色框位于页面的顶角而不是容器元素的内部。

您可以在下面找到小提琴的简化版本:

#outer {
    position:relative; 
    -webkit-transform:translate3d(0px, 20px , 0px); 
    height: 300px; 
    border: 1px solid #5511FF; 
    padding: 10px;
    background: rgba(100,180,250, .8); 
    width: 80%;
}
#middle{
    position:relative; 
    border: 1px dotted #445511; 
    height: 300px; 
    padding: 5px;
    background: rgba(250,10,255, .6);
}
#inner {
    position: fixed; 
    top: 0px;
    box-shadow: 3px 3px 3px #333; 
    height: 20px; 
    left: 0px;
    background: rgba(200,180,80, .8); 
    margin: 5px; 
    padding: 5px;
}
<div id="container">
    Blue: Outer, <br>
    Purple: Middle<br>
    Yellow: Inner<br>
    <div id="outer"> 
        <div id="middle">
            <div id="inner">
                Inner block
            </div>
        </div>
    </div>
</div>

如何使 translate3d 与固定位置的孩子一起工作?

4

10 回答 10

217

这是因为根据W3C 规范transform创建了一个新的局部坐标系:

在 HTML 命名空间中,除了none转换之外的任何值都会导致创建堆栈上下文和包含块。该对象充当固定定位后代的包含块。

这意味着固定定位固定在转换后的元素上,而不是视口上。

目前没有我知道的解决方法。

它也记录在 Eric Meyer 的文章:Un-fixing Fixed Elements with CSS Transforms中。

于 2013-03-06T19:31:47.480 回答
13

正如 Bradoergo 建议的那样,只需获取窗口scrollTop并将其添加到绝对位置顶部,如:

function fix_scroll() {
  var s = $(window).scrollTop();
  var fixedTitle = $('#fixedContainer');
  fixedTitle.css('position','absolute');
  fixedTitle.css('top',s + 'px');
}fix_scroll();

$(window).on('scroll',fix_scroll);

无论如何,这对我有用。

于 2014-01-31T18:59:07.850 回答
13

当页面中的项目使用转换时,我的固定顶部导航闪烁,以下应用于我的顶部导航解决了跳跃/闪烁问题:

#fixedTopNav {
    position: fixed;
    top: 0;
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
}

感谢这个答案

于 2015-04-07T15:48:07.073 回答
5

在 Firefox 和 Safari 中,您可以使用position: sticky;代替,position: fixed;但它在其他浏览器中不起作用。为此,您需要 javascript。

于 2015-12-14T18:45:53.807 回答
3

在我看来,解决这个问题的最佳方法是应用相同的翻译,但将需要修复的子元素从其父(已翻译)元素中分离出来;然后将翻译应用于position: fixed包装器内的 div 。

结果看起来像这样(在你的情况下):

<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 

</div>
<div style='position: fixed; top: 0px; 
            box-shadow: 3px 3px 3px #333; 
            height: 20px; left: 0px;'>
    <div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
        Inner block
    </div>
</div>

JSFiddle:https ://jsfiddle.net/hju4nws1/

虽然这对于某些用例可能并不理想,但通常如果您正在修复一个 div,您可能不太关心它的父元素/它在 DOM 中的继承树中的位置,并且似乎解决了大部分令人头疼的问题- 同时仍然允许两者translateposition: fixed生活在(相对)和谐中。

于 2017-03-07T23:32:08.113 回答
0

我遇到了同样的问题。唯一的区别是我的“位置:固定”元素的“顶部”和“左侧”样式属性是从 JS 设置的。所以我能够应用修复:

var oRect = oElement.getBoundingClientRect();

oRect 对象将包含真实的(相对于视口)顶部和左侧坐标。所以你可以调整你的实际 oElement.style.top 和 oElement.style.left 属性。

于 2013-07-22T12:29:52.647 回答
0

我有一个使用 -webkit-transform: translate3d 的画布侧边栏。这使我无法在页面上放置固定页脚。我通过在侧边栏初始化时添加到标签中的 html 页面上的一个类解决了这个问题,然后编写一个 css :not 限定符来声明“-webkit-transform: none;” 当 html 标记上不存在该类时,将其添加到 html 标记。希望这可以帮助解决同样问题的人!

于 2016-06-22T21:19:25.100 回答
0

尝试对子元素应用相反的变换:

<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(-100%, 0px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>
于 2016-08-06T13:59:02.770 回答
0

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

.translat3d(@x, @y, @z) { 
     -webkit-transform: translate3d(@X, @y, @z); 
             transform: translate3d(@x, @y, @z);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

然后

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

然后

.transformed {
    #elementId { 
        .translate3d(0px, 20px, 0px);
    }
}

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

于 2018-07-30T19:08:19.557 回答
-1

解决此问题的一种方法是将相同的变换应用于固定元素:

<br>
<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(0px, 20px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>
于 2015-09-03T04:07:37.920 回答