Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Position fixed does not work with transform CSS property [duplicate]

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?

like image 969
Juan Carlos Moreno Avatar asked Mar 04 '13 03:03

Juan Carlos Moreno


People also ask

Why is position fixed not working in CSS?

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.

Why is my position fixed when I transform an 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.

What is the relationship between position fixed and transform property?

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.

How do CSS transforms work?

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.


3 Answers

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.

like image 137
saml Avatar answered Oct 07 '22 17:10

saml


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.

like image 39
UzumakiDev Avatar answered Oct 07 '22 17:10

UzumakiDev


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.

like image 28
Dušan Avatar answered Oct 07 '22 17:10

Dušan