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:
#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>
How can I make translate3d work with fixed-positioned children?
If you’re using position:fixed and it’s not working there’s a chance you came across a known bug. Position fixed doesn’t work with transform CSS property. It happens because transform creates a new coordinate system and your position: fixed element becomes fixed to that transformed element.
It happens because transform creates a new coordinate system and your position: fixed element becomes fixed to that transformed element. To fix the problem you can remove transform CSS property from the parent element.
The uncanny relationship between position fixed and transform property. An element with position:fixed is positioned relative to the document (the viewport) which acts as its containing block. But, it will NOT always be relative to the document.
argument... The CSS Transforms spec explains this behavior. Elements with transforms act as a containing block for fixed position descendants, so position:fixed under something with a transform no longer has fixed behavior. They do work when applied to the same element; the element will be positioned as fixed, and then transformed.
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.
As Bradoergo suggested, just get the window scrollTop
and add it to the absolute position top like:
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);
This worked for me anyway.
In Firefox and Safari you can use position: sticky;
instead of position: fixed;
but it will not work in other browsers. For that you need javascript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With