'transform3d'不适用于位置:固定子级


140

我在哪里,在正常情况下,CSS,固定股利将正好它被指定的(定位的情况下top:0pxleft:0px)。

如果我的父母有一个translate3d转换,这似乎不被尊重。我没看到什么吗?我尝试了其他webkit转换,例如样式和转换原点选项,但没有运气。

我在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与固定位置的孩子一起工作?


过滤器也会发生相同的问题:stackoverflow.com/q/52937708/8620333
Temani Afif

Answers:


196

这是因为transform按照W3C规范,会创建一个新的本地坐标系:

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

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

我目前不知道有解决方法。

埃里克·迈耶(Eric Meyer)的文章:使用CSS变换解除固定元素的固定也对此进行了记录。


谢谢,我没有注意到实际的规格中有该信息.....我想我得到了与数学答案相当的东西:“按定义” :)
Juan Carlos Moreno

3
@INT,我不认为会有解决方法。有一个主要的用例,它不允许解决方法:用户提供的输入可能会覆盖其指定区域之外的控件(请考虑将恶意电子邮件添加到gmail工具栏)。最好的解决方法是暂时避免使用内部固定的转换。
saml 2013年

1
不会将CSS top属性设置为任何可以工作的window.scrollHeight吗?您可能也必须绝对定位它,但是这样的事情应该可行,不是吗?(太懒了,无法立即进行实际测试)
Brad Orego 2014年

@bradorego,您是对的,我只是添加了我使用的代码。
UzumakiDev 2014年

据我所知,这仍然在规范中不断变化。请参见错误16328-使用“包含块”与CSS2.1定义不匹配
第三方2014年

13

当页面中的项目正在使用transform时,我的固定导航栏上出现了闪烁,将以下内容应用于顶部导航栏解决了跳跃/闪烁问题:

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

感谢这个答案


12

正如Bradoergo建议的那样,只需获取窗口scrollTop并将其添加到绝对位置top即可,如下所示:

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
有用!但是我没有绑定到“窗口”,而是不得不绑定到正在滚动的div。而且,固定元件会闪烁。
火车

jQuery在这里做什么?
FlorianB '16

这可以做到,但就像提到的@train一样,它会闪烁。
Etienne Dupuis,2016年

是的,对于我的使用而言,更新速度不够快,不够干净:-/好主意
里德,2017年

这是非常糟糕的做法,请不要使用js进行样式更改
Wannes

4

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


2
粘性定位是相对定位和固定定位的混合体,它确实是实验性的,强烈建议您避免这种情况,因为它不是标准的。
远端

1
您可以轻松使用Firefox和Safari上的AFAIK,position:fixed无论如何它都可以正常工作。
oriadam

@oriadam不,当父母使用translate3d且孩子的固定位置在某些情况下飞来飞去时,我遇到了问题。将sticky在主要浏览器已经支持的情况下尝试使用:caniuse.com/#feat=css-sticky
Lukas Liesis

sticky可能是一种解决方案,它可以在现代浏览器上运行。
aboutqx

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住在(相对)的和谐。


0

我遇到了同样的问题。唯一的区别是,我的“ position:fixed”元素具有从JS设置的“ top”和“ left”样式属性。这样我就可以应用修复程序:

var oRect = oElement.getBoundingClientRect();

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


这适用于IE和Chrome,但不适用于Android标准浏览器。左边是数字,但始终画在位置0上
Adaptabi

0

我有一个使用-webkit-transform的非画布侧边栏:translate3d。这使我无法在页面上放置固定的页脚。通过在侧边栏初始化时添加到标签的html页面上定位一个类,然后编写一个css:not限定符以声明“ -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

在元素变形时添加动态类。$('#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属性值时,它可以很好地工作并保持固定,直到父元素变形为止。恢复转换后,子元素将再次按固定方式弹出。如果您实际上使用的导航侧栏可以在单击时切换打开和关闭,并且应该有一个选项卡集,当您向下滚动页面时,该选项卡集应该保持粘性,这应该可以缓解这种情况。


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

1
在IE错误不会在首位存在
oriadam
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.