'transform3d'不适用于职位:固定子女

问题描述 投票:125回答:10

我有一种情况,在正常的CSS情况下,固定的div将准确定位在指定的位置(top:0pxleft: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与固定定位的孩子一起工作?

html css css3 css-position css-transforms
10个回答
178
投票

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

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

这意味着固定定位将固定到变换后的元素,而不是视口。

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

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


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

13
投票

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

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

Thanks to this answer on SO


12
投票

正如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);

无论如何,这对我有用。


3
投票

在Firefox和Safari中,您可以使用position: sticky;而不是position: fixed;,但它不适用于其他浏览器。为此你需要javascript。


3
投票

在我看来,解决这个问题的最好方法是应用相同的翻译,但要打破需要修复其父(翻译)元素的子项;然后将translate应用于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生活在(相对)和谐中。


0
投票

我遇到了同样的问题。唯一的区别是我的'position:fixed'元素有JS设置的'top'和'left'样式属性。所以我能够应用修复:

var oRect = oElement.getBoundingClientRect();

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


0
投票

我有一个使用-webkit-transform:translate3d的画布边栏。这阻止我在页面上放置固定的页脚。我通过在html页面上定位一个类来解决这个问题,该类在边栏的初始化时添加到标记,然后编写一个css:not qualifier to state“-webkit-transform:none;”当html标记上没有该类时,html标记。希望这可以帮助那些有同样问题的人!


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>

0
投票

在元素transforms.$('#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在子元素上提供topz-index属性值时工作正常并保持固定直到父元素转换​​。当转换被还原时,子元素再次弹出为固定。如果您实际上使用导航侧边栏切换打开并在单击时关闭,这应该可以缓解这种情况,并且您有一个标签集,当您向下滚动页面时,该标签集应保持粘性。

© www.soinside.com 2019 - 2024. All rights reserved.