Position fixed doesn't work when using -webkit-transform
Asked Answered
S

21

177

I am using -webkit-transform (and -moz-transform / -o-transform) to rotate a div. Also have position fixed added so the div scrolls down with the user.

In Firefox it works fine, but in webkit based browsers it's broken. After using the -webkit-transform, the position fixed doesn't work anymore! How is that possible?

Selfimmolation answered 14/4, 2010 at 11:51 Comment(11)
A demo page often helps people answer questions - jsbin.com lets you make temporary pages to illustrate the problem if you don't want to link to your site.Lycopodium
jsfiddle.net is another good example of a temporary editing bin.Hog
@Rich Bradshaw jsbin.com is very nice. Didn't know it until now. Most of my projects I run local, so I will use it next time. TnxSelfimmolation
@Selfimmolation You can easily apply a workaround by defining the fixed element directly on the body or adding it to the body with jQuery/JavaScript.Gus
As of 06/2013 it's always broken for my Webkit 28.x.x, here the test jsfiddle.net/molokoloco/zhTR4Larrigan
It doesn't work fine in Firefox at all.Travers
See also SO: webkit css 'transform3d' + 'position: fixed' issue. This is tentatively part of the W3C spec, which would make it the correct behavior for the browser (but the spec definitions are in flux).Saccharose
Here is an article talking about this bug and there is a link to a simple exemple: meyerweb.com/eric/thoughts/2011/09/12/…Bodi
Still an issue in 2017. Seems that they're still sticking to the "It's a feature not a bug!" argument...Experienced
Just want to add another live demo that demonstrates the bug poet.codes/e/PMVjDNz0VCx#styles.cssRescue
10 yrs later ....... and not even a work-around. Maybe someone should suggest that they add a way to exclude children from a transformationDemonstrator
H
95

After some research, there has been a bug report on the Chromium website about this issue, so far Webkit browsers can't render these two effects together at the same time.

I would suggest adding some Webkit only CSS into your stylesheet and making the transformed div an image and using it as the background.

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

So for now you'll have to do it the old fashioned way, until Webkit browsers catch up to FF.

EDIT: As of 10/24/2012 the bug has not been resolved.


This appears to not be a bug, but an aspect of the specification due to the two effects requiring separate coordinate systems and stacking orders. As explained in this answer.

Hog answered 14/4, 2010 at 12:25 Comment(40)
@Hog Sevenoaks Tnx for your awnser. Helps a lot :).Selfimmolation
Just so u know. I decided to remove the button in webkit based browsers :). Customer doesn't use it anyway. Until webkit based browser catch up with ff, I don't support it. Not the best solution, but for now the quickest...Selfimmolation
Well that makes sense if the customers don't even use it, why bother putting it in? Hope that Webkit catches up, also that the other browsers catch up to the webkit transitions!Hog
That would be really nice. There are a lot of CSS3 functions I want to use :). So you know, I made (my first) a jQuery plugin for it. bit.ly/cVWxvR. Really simple, but usefull!Selfimmolation
I have used CSS3 functions for the special users of webkit browsers, but others just have to wait. Making jQuery plugins is a great way to go about it, keep up the good work!Hog
The problem is what happens if it's a navigation and not just a ribbon. You need clickable elements, I think I'm going for a JS based solution.Cambrian
Thanks, I had the same problem with repositioning a fixed element with top: 0. It simply did not show. My fix is by removing the attribute when set to 0 (which was my use case). Simply add your object with jQuery's css function and along the lines of transform: '' and '-webkit-transform': ''.Capful
Even more years later, still not resolved. Pretty sad.Conclusive
According to this answer it's not a bug but part of the spec.Sweitzer
find firfox has the same problem.Coffeecolored
April 1, 2016 – still busted :[Sourpuss
25 May, 2016 Still not working, ended up just removing the transformUlceration
I've been looking at a solution for this since a bug came up on a website I was working on. The previous developer somehow managed to achieve this but he had some mistakes on the html leaving some open tags. Once I fixed the missing closing tags I crashed into this exact problem and I am scouring the internet looking for an almost impossible solution... until I've found this fiddle: jsfiddle.net/vishl/wzpsf where as you can see the fixed element is working correctly. Someone knows what's happening here and can shed some light on it?Artemis
@Artemis The fixed element isn't inside the transformed element.Ashurbanipal
How is this still not fixed ? It's been 6 years.Gable
Added link to explanation, thanks to @MichaelRushton for pointing it out.Hog
sit back and watch -- I bet it will live to its 10 year anniversaryPilsen
May 2017. Still an issue.Fideicommissum
sigh May 17, 2017Landri
End of July, 2017 -- they still don't know I'm a soviet spy, chrome translate3d with fixed still not working. Signing off.Pendergast
Aug 30, 2017, captain's log. We also have encountered the strange anomaly, which was described so long ago by other captains. A solution is still to be implemented.Morman
Feb 2018: we seem to have encountered some kind of ancient technology, no one can explainCappello
March, 2018: Still my firefox dev edition is punching me down with this issue... :(Rosabelle
This is the bug that my father's father warned me about.Talaria
January 2019: This bug is still going strongRedden
The 3rd month of the 19th year of the 2nd Millennium, still not resolvedYuzik
Summer 2019 checking in.Markettamarkey
September 2019 !Nonlegal
October (1 day short of november) 2019 checking in. I thought I was going crazy. The fact that it hasn't been fixed 9.5 years later is mind boggling.Thirddegree
9 years, 9 month. We are getting close!Selfexpression
This bug is giving me more trouble than the coronavirus pandemic 26 March 2020!Oswaldooswalt
We made it to 10 years guys!Schnabel
When you come to SO looking for answers, this is exactly the kind of comment thread you don't want to see.Leaves
2021 and the bug still hasn't been resolvedCircumstance
and it 2022 nowPice
I come every now and then to checkout the comments section lol, Jan 10 2022 and still...Circumstance
This answer is older than my children, and I'm quite sure they'll never be fixed either.Hog
10th anniversary, next up 20th anniversary. My great great children will probably face this bug too it seemsDemonstrator
new year and it's still hereButch
Hello 2025. This is a time capsule from 2022. Please let the developer know this issue still existsDried
C
131

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.

Churchly answered 21/6, 2016 at 20:16 Comment(2)
That's the only helpful and correct answer. Stop translating the parent element and translate the childlements where the fixed element is part of it. Here's my fiddle:JSFIDDLEAshurbanipal
and what if I want to transform a fixed element too?Kisangani
H
95

After some research, there has been a bug report on the Chromium website about this issue, so far Webkit browsers can't render these two effects together at the same time.

I would suggest adding some Webkit only CSS into your stylesheet and making the transformed div an image and using it as the background.

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

So for now you'll have to do it the old fashioned way, until Webkit browsers catch up to FF.

EDIT: As of 10/24/2012 the bug has not been resolved.


This appears to not be a bug, but an aspect of the specification due to the two effects requiring separate coordinate systems and stacking orders. As explained in this answer.

Hog answered 14/4, 2010 at 12:25 Comment(40)
@Hog Sevenoaks Tnx for your awnser. Helps a lot :).Selfimmolation
Just so u know. I decided to remove the button in webkit based browsers :). Customer doesn't use it anyway. Until webkit based browser catch up with ff, I don't support it. Not the best solution, but for now the quickest...Selfimmolation
Well that makes sense if the customers don't even use it, why bother putting it in? Hope that Webkit catches up, also that the other browsers catch up to the webkit transitions!Hog
That would be really nice. There are a lot of CSS3 functions I want to use :). So you know, I made (my first) a jQuery plugin for it. bit.ly/cVWxvR. Really simple, but usefull!Selfimmolation
I have used CSS3 functions for the special users of webkit browsers, but others just have to wait. Making jQuery plugins is a great way to go about it, keep up the good work!Hog
The problem is what happens if it's a navigation and not just a ribbon. You need clickable elements, I think I'm going for a JS based solution.Cambrian
Thanks, I had the same problem with repositioning a fixed element with top: 0. It simply did not show. My fix is by removing the attribute when set to 0 (which was my use case). Simply add your object with jQuery's css function and along the lines of transform: '' and '-webkit-transform': ''.Capful
Even more years later, still not resolved. Pretty sad.Conclusive
According to this answer it's not a bug but part of the spec.Sweitzer
find firfox has the same problem.Coffeecolored
April 1, 2016 – still busted :[Sourpuss
25 May, 2016 Still not working, ended up just removing the transformUlceration
I've been looking at a solution for this since a bug came up on a website I was working on. The previous developer somehow managed to achieve this but he had some mistakes on the html leaving some open tags. Once I fixed the missing closing tags I crashed into this exact problem and I am scouring the internet looking for an almost impossible solution... until I've found this fiddle: jsfiddle.net/vishl/wzpsf where as you can see the fixed element is working correctly. Someone knows what's happening here and can shed some light on it?Artemis
@Artemis The fixed element isn't inside the transformed element.Ashurbanipal
How is this still not fixed ? It's been 6 years.Gable
Added link to explanation, thanks to @MichaelRushton for pointing it out.Hog
sit back and watch -- I bet it will live to its 10 year anniversaryPilsen
May 2017. Still an issue.Fideicommissum
sigh May 17, 2017Landri
End of July, 2017 -- they still don't know I'm a soviet spy, chrome translate3d with fixed still not working. Signing off.Pendergast
Aug 30, 2017, captain's log. We also have encountered the strange anomaly, which was described so long ago by other captains. A solution is still to be implemented.Morman
Feb 2018: we seem to have encountered some kind of ancient technology, no one can explainCappello
March, 2018: Still my firefox dev edition is punching me down with this issue... :(Rosabelle
This is the bug that my father's father warned me about.Talaria
January 2019: This bug is still going strongRedden
The 3rd month of the 19th year of the 2nd Millennium, still not resolvedYuzik
Summer 2019 checking in.Markettamarkey
September 2019 !Nonlegal
October (1 day short of november) 2019 checking in. I thought I was going crazy. The fact that it hasn't been fixed 9.5 years later is mind boggling.Thirddegree
9 years, 9 month. We are getting close!Selfexpression
This bug is giving me more trouble than the coronavirus pandemic 26 March 2020!Oswaldooswalt
We made it to 10 years guys!Schnabel
When you come to SO looking for answers, this is exactly the kind of comment thread you don't want to see.Leaves
2021 and the bug still hasn't been resolvedCircumstance
and it 2022 nowPice
I come every now and then to checkout the comments section lol, Jan 10 2022 and still...Circumstance
This answer is older than my children, and I'm quite sure they'll never be fixed either.Hog
10th anniversary, next up 20th anniversary. My great great children will probably face this bug too it seemsDemonstrator
new year and it's still hereButch
Hello 2025. This is a time capsule from 2022. Please let the developer know this issue still existsDried
A
12

Something (a bit hacky) that worked for me is to position:sticky instead:

.fixed {
     position: sticky;
}
Agonic answered 21/7, 2013 at 15:2 Comment(2)
updates.html5rocks.com/2012/08/… ah yeah.. but not well supported yet it seemsVaranasi
This is the right solution in 2022. position: sticky is widely supported, and it fixes this behaviour.Transducer
N
7

For anyone who finds their background images are disappearing in Chrome because of the same issue with background-attachment: fixed; - this was my solution:

// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    // set background-attachment back to the default of 'scroll'
    $('.imagebg').css('background-attachment', 'scroll');

    // move the background-position according to the div's y position
    $(window).scroll(function(){

        scrollTop = $(window).scrollTop();
        photoTop = $('.imagebg').offset().top;
        distance = (photoTop - scrollTop);
        $('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');

    });
}  
Noctambulous answered 13/1, 2014 at 23:43 Comment(0)
H
7

August 2016 and fixed position & animation / transform is still a problem. The only solution that worked for me – was to create an animation for the child element that takes longer time.

Homophony answered 16/8, 2016 at 19:45 Comment(4)
Please answer to new questions. Those questions need you more rather than the person who asked question in 2010. They must have solved the problem by now don't you think ? Also this question already has an accepted answer.Fiedler
Nope! It's still a problem... the person who asked the question might have found another solution – but I found this thread for a reason.Homophony
As you wish. I left that comment while reviewing first questions by people. And since you have joined just today and it was your first answer and also a late answer so that is why I left that comment. I didn't downvote. That is a good chance for you.Fiedler
@UmairFarooq maybe asking another question would be useless because it could be marked as duplicate. I came here just with a google search and i found this question useful , defligra answer too.Timber
J
3

Actually I found another way to fix this "bug":

I have container element which hold page with css3 animations. When the page completed the animation, the css3 property has value: transform: translate(0,0);. So, I just removed this line, and everything worked as it should - position: fixed is displayed properly. When css class is applied to translate the page, translate property is added and css3 animation worked as well.

Example:

.page {
     top: 50px;
     position: absolute;
     transition: ease 0.6s all;
     /* -webkit-transform: translate(0, 0); */
     /* transform: translate(0,0); */
 }
 .page.hide {
     -webkit-transform: translate(100%, 0);
     transform: translate(-100%, 0);    
 }

Demo: http://jsfiddle.net/ZWcD9/

Junitajunius answered 17/7, 2014 at 15:55 Comment(2)
For me, it was the fact of having these styles on the wrapper containing the fixed element that was preventing the fixed one from being sticky: -webkit-perspective: 1000; -webkit-transform-style: preserve-3d; Took these off and everything works fine. They were questionable optimizations anyway!Conclusive
Removing the transform, by any means, is probably the best workaround so far. Something like a fade-in, once complete, should be removable without affecting the appearance of the element. Actually, I'm not sure what having a transformX(0) hanging around would do to rendering performance, if anything at all; it could either be ignored, or could hurt performance, or could make it better by forcing some kind of 3D acceleration. Who knows. In any case, once an animation is complete, or even just before a fixed element is added to it, one can simply remove the CSS classes for the transform.Frisette
D
2

I had this issue whilst trying to implement react-color with react-swipeable-views (rsw). The problem for me was that rsw applies translate(-100%, 0) to a tab panel which breaks the default fixed position div added over the full screen which when clicked closes the color picker model.

For me the solution was to apply the opposite transform to the fixed element (in this case translate(100%, 0) which fixed my issue. I'm not sure if this is useful in other cases but thought I would share anyway.

Here is an example showing what I've described above:

https://codepen.io/relativemc/pen/VwweEez

Dichromatic answered 13/10, 2019 at 16:24 Comment(0)
M
2

Setting fixed element to transform:unset; is working for me.

Misprint answered 27/10, 2022 at 20:44 Comment(0)
A
2

If you work with React, you can wrap the element with fixed position in a Portal, and this way it will work fine

Aftermath answered 11/2, 2023 at 1:35 Comment(0)
C
1

on my phonegap project the webkit transform -webkit-transform: translateZ(0); worked like a charm. It was already working in chrome and safari just not the mobile browser. also there can be one more issue is WRAPPER DIVs are not completed in some cases. we apply clear class in case of floating DIVs.

<div class="Clear"></div> .Clear, .Clearfix{clear:both;}
Coupe answered 7/4, 2013 at 4:29 Comment(0)
M
1

Probably due to a bug in Chrome as I can't replicate in Safari nor Firefox, but this works in Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

It's a very particular structure so it's by no means a universally applicable one-lined css fix, but perhaps someone can tinker with it to get it working in Safari and Firefox.

Michaelis answered 13/2, 2015 at 14:5 Comment(0)
K
1

I just added transform: unset; to my fixed header and that worked for me!

I am also using framer motion with Next.js and having the same problem with my fixed header and this seems to fix it easily.

.header {
    position: fixed;
    transform: unset;
}
Kimi answered 27/10, 2022 at 20:33 Comment(0)
F
0

Adding the -webkit-transform to the fixed element solved the issue for me.

.fixed_element {
   -webkit-transform: translateZ(0);
   position: fixed;
   ....
} 
Flogging answered 6/3, 2013 at 15:23 Comment(6)
That didn't work for me. Are you able to create a demo of it working?Onomasiology
i posted this solution because all the others didn't work for me. But im my case it was Safari-specific, even Chrome didn't need this fix. maybe try to experiment a bit with the transform...?Flogging
This fixed an issue for me in Chrome, FWIW. Thanks Ron.Shuttering
FYI, on Android 2.3 this does not fix the issue.Dulcinea
@Neil Monroe, Android 2.3 is a whole new story. It does not support the fixed positioning at all :)Paragraph
Here is a Fiddle where using translateZ(0) DOES NOT work. It's true that it works sometimes, I've seen occasions where it worked. But I still cannot narrow it down.Ozonosphere
R
0

Here is what works for me on all tested browsers and mobile devices (Chrome, IE, Firefox, Safari, iPad, iphone 5 and 6, Android).

img.ui-li-thumb {
    position: absolute;
    left: 1px;
    top: 50%;

    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}
Raddi answered 14/5, 2015 at 17:57 Comment(1)
Why the downvotes? It would be nice if you supplied a comment as to why you down voted my answer?Raddi
D
0

the fixed position of an element is broken if you apply transform to any ancestor.

<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok

<div style='-.*-transform:scale(2)'>
      <div style='position:fixed'>...</div> // broken
</div>
Dulcia answered 23/6, 2015 at 9:17 Comment(0)
C
0

If you can use javascript as an option this can be a workaround for positioning a position fixed element relavtive to the window when it's inside a transformed element:

  let fixedEl // some node that you is position 
              // fixed inside of an element that has a transform

  const rect = fixedEl.getBoundingClientRect()
  const distanceFromWindowTop = rect.top
  const distanceFromWindwoLeft = rect.left
  let top = fixedEl.offsetTop
  let left = fixedEl.offsetLeft

  if(distanceFromWindowTop !== relativeTop) {
    top = -distanceFromWindowTop
    fixedEl.style.top = `${top}px`
  }

  if(distanceFromWindowLeft !== relativeLeft) {
    left = -distanceFromWindowLeft
    fixedEl.style.left = `${left}px`
  }

Granted you will also have to adjust your heights and width because fixedEl will be calculating it's with based on it's container. That depends on your use case but this will allow you to predictably set the something position fixed, regardless of it's container.

Cassiterite answered 11/8, 2017 at 1:34 Comment(0)
Y
0

Add a dynamic class while the element transforms.$('#elementId').addClass('transformed'). Then go on to declare in css,

.translatX(@x) { 
     -webkit-transform: translateX(@X); 
             transform: translateX(@x);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

then

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

then

.transformed {
    #elementId { 
        .translateX(@neededValue);
    }
}

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.

Yurik answered 31/7, 2018 at 15:32 Comment(0)
A
0

in my case I found out we can't use transform: translateX() before transform:translateY().if we want to use both we should use transform:translate( , ).

Archway answered 15/2, 2020 at 10:39 Comment(0)
W
0

If you're animating back to the original position where all translates are 0, you can use this solution where you set transform: unset;:

  100% {
    opacity: 1;
    visibility: visible;
    /* Use unset to allow fixed elements instead of translate3d(0, 0, 0) */
    transform: unset;
  }
Wirephoto answered 8/10, 2020 at 8:52 Comment(0)
O
0

If you use React then you can use ReactDOM.createPortal.

Credit goes for Porkopek for the tip, but it took me some time to figure out what this thing is. So here's what I found:

If you return a component wrapped in ReactDOM.createPortal then as the second argument you can set the parent element, and React will append the component to that given element, so example position: fixed will be fine even as a child of a transformed component.

import ReactDOM from "react-dom";


const MyModal = () => {
    return ReactDOM.createPortal(
       <div style={{position: "fixed", top: "0", left: "0", 
                    background: "white", color: "black", 
                    padding: "3rem", zIndex: "50000"}}>
         Modal Element
       </div>,
       document.body
    )

}

In this case React will render this component as the child of the body, not as the child of the parent component.

Ostosis answered 9/3, 2023 at 20:36 Comment(0)
F
-1

Please don't up vote, because this is not exact answer, but could help someone because it's fast way just to turn off the transformation. If you really don't need the transformation on the parent and you want your fixed position working again:

#element_with_transform {
  -webkit-transform: none;
  transform: none;
}
Frida answered 8/8, 2017 at 14:5 Comment(2)
This is, like, really in the question's titleFolliculin
@EugenePankov Don't see 'none' in the title. It was what it fixed my problem and in general no one suggests to turn it off. Although this is not exact answer to that question, but it could help someone that doesn't want to use transformation and the transformation comes from an other library. So I don't want up votes, but please don't down vote. I will edit my question to say that I don't want Up vote.Frida

© 2022 - 2024 — McMap. All rights reserved.