'transform3d' not working with position: f

2018-12-31 06:11发布

I have a situation where, in normal CSS circumstances, a fixed div would be positioned exactly where it is specified (top:0px, left:0px).

This does not seem to be respected if I have a parent that has a translate3d transform. Am I not seeing something? I have tried other webkit-transform like style and transform origin options but had no luck.

I have attached a JSFiddle with an example where I would have expected the yellow box be at the top corner of the page rather than inside of the container element.

You can find below a simplified version of the fiddle:

<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; 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'
    >
        Inner block
    </div>
</div>

Any pointers to make the translate3d work with a fixed-positioned children will be appreciated.

11条回答
还给你的自由
2楼-- · 2018-12-31 06:13

Add a dynamic class while the element transforms.$('#elementId').addClass('transformed'). Then go on to declare in 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 
}

then

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

then

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

Now position: fixed when provided with a top and z-index property values on a child element just work fine and stay fixed until the parent element transforms. When the transformation is reverted the child element pops as fixed again. This should easen the situation if you are actually using a navigation sidebar that toggles open and closes upon a click, and you have a tab-set which should stay sticky as you scroll down the page.

查看更多
深知你不懂我心
3楼-- · 2018-12-31 06:14

I had a flickerings on my fixed top nav when items in the page were using transform, the following applied to my top nav resolved the jumping/flickering issue:

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

Thanks to this answer on SO

查看更多
初与友歌
4楼-- · 2018-12-31 06:16

This is because the transform creates a new local coordinate system, as per W3C spec:

In the HTML namespace, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.

This means that fixed positioning becomes fixed to the transformed element, rather than the viewport.

There's not currently a work-around that I'm aware of.

It is also documented on Eric Meyer's article: Un-fixing Fixed Elements with CSS Transforms.

查看更多
浮光初槿花落
5楼-- · 2018-12-31 06:19

Try to apply opposite transform to the child element:

<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>
查看更多
浪荡孟婆
6楼-- · 2018-12-31 06:24

I'm having similar issue and I believe there's work around it. I'm using snap.js and I want one of the child divs of the content container to be fixed to its position. However, when the drawer opens, the JavaScript fires the transform:translate3d property for the parent container and this also affects the fixed child element (the fixed element moves along with its parent and stays fixed in the new position).

With this being said, the fixed property becomes partially useless. To solve this, an event listener can be added which would fire up a separate tranform:translate3d for the fixed child div. And the direction of this translate should be opposite to the parent's transform:translate3d.

The only problem is that I don't know how to write it and it would've been cool if somebody took a stab at it.

查看更多
无色无味的生活
7楼-- · 2018-12-31 06:26

I have an off canvas sidebar that uses -webkit-transform: translate3d. This was preventing me from placing a fixed footer on the page. I resolved the issue by targeting a class on the html page that is added to the tag on initialization of the sidebar and then writing a css :not qualifier to state "-webkit-transform: none;" to the html tag when that class is not present on the html tag. Hope this helps someone out there with this same issue!

查看更多
登录 后发表回答