68

my question is pretty simple. I'm working on a page on mobile version, and we want to keep the "snag it" yellow button fixed on bottom, but position fixed is not working, it's working like position absolute and i don't know why.

The page i'm working: https://www.thechivery.com/products/everything-is-j-ok-tee

Thanks, Luiz

Luiz Mitidiero
  • 1,130
  • 1
  • 10
  • 22
  • 5
    The use of `-webkit-transform:translate3d(0,0,0)` on the `.content-container` class throws off the `fixed` positioning context, and the positioning becomes relative to the class the transform was declared on rather than the viewport. See [this SO answer](http://stackoverflow.com/questions/25824749/why-webkit-transform-translate3d0-0-0-messes-up-with-fixed-childs). Remove that rule and your fixed element will work as normal. – litel Apr 26 '16 at 05:41
  • 1
    Here's a super simple fiddle demonstrating how the transform destroys the `fixed` positioning: https://jsfiddle.net/p7oy6fL4/ – litel Apr 26 '16 at 05:45
  • Hey man, it's exactly what you said! Don't you want to answer so i can elect your answer? Thanks! – Luiz Mitidiero Apr 26 '16 at 06:17
  • Adding 'filter' property on the parent element also causes that. – Muhammad Mabrouk Mar 23 '21 at 17:38

4 Answers4

147

The issue here lies with your .content-container wrapper class, which has a CSS declaration of webkit-transform: translate3d(0,0,0). The transform declaration, as this answer illustrates, changes the positioning context from the viewport to the rotated element, which essentially means that your fixed element behaves as if it were absolutely positioned. Here's an example showing the difference between a fixed element inside a transformed div and a fixed element outside of that div.

.rotate {
  transform: rotate(30deg);
  background: blue;
  width: 300px;
  height: 300px;
  margin: 0 auto;
}
.fixed {
  position: fixed;
  background: red;
  padding: 10px;
  color: white;
  top: 50px;
}
<div class="rotate">
  <div class="fixed"> I am fixed inside a rotated div.</div>
</div>
<div class="fixed"> I am fixed outside a rotated div.</div>

In order for everything to work, you'll need to remove the transform3d declaration from .content-container.

Maximillian Laumeister
  • 19,884
  • 8
  • 59
  • 78
litel
  • 3,790
  • 3
  • 20
  • 29
  • 6
    Just wanted to add that the 'perspective' property also triggers this bug. If you get this issue in future, the easiest way to diagnose is to drag the element up through each of its ancestors until it starts behaving - then look for suspect properties on the offending element. – phayton Aug 18 '16 at 14:59
  • 1
    Thank you! I didn't know this was thing.... How odd. – Joshua Russell Feb 01 '17 at 05:01
  • If we don't apply that css, then elements are disappear and appear again. How to avoid this without getting this issue? http://stackoverflow.com/questions/9807620/ipad-safari-scrolling-causes-html-elements-to-disappear-and-reappear-with-a-dela – Jeeva J Mar 06 '17 at 09:05
  • 10
    `will-change` appears to have the same effect of changing the context. – Dan Eastwell Mar 15 '17 at 13:38
  • 3
    @DanEastwell Correct, `will-change` creates [a stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context) just like `transform` does. – adam b Apr 03 '17 at 13:46
  • -webkit-overflow-scrolling in the parent element also causes this problem – user1843640 Apr 18 '19 at 17:33
  • Just to clarify, you *can* use `transform` on the own element. That bug affects when using `transform` (or the other attributes pointed) on the *parent* (in any level) element. – sdlins Jun 23 '19 at 03:17
  • Very smart analysis, thanks @Maximilian I encountered same problem within a transform: translateX() container. I could set a workaround based on position: relative + left properties – ZalemCitizen Mar 15 '20 at 23:01
  • 2
    `filter` also causes this problem, so check the element's ancestors for `filter`. – Marius Apr 15 '20 at 11:42
  • Was stuck on this issue for ages with CodeMirror autocompletion not showing – apc Feb 23 '23 at 14:21
13

For anyone wondering if this is a browser bug. Apparently it's not and it follows current W3C specs. What's strange is at first it was just inconsistent between the browsers (in some it worked as intended) and then all of them started to follow the counter intuitive W3C rules. There seems to be no clear explanation if this is actually intended logic, a side effect of some implementation problem or just a dumb omission.

Also position: fixed gets broken not only by transform but also by filter and perspective property put on any ancestor as explained here.

See: https://www.w3.org/TR/css-transforms-1/#propdef-transform and https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 and https://github.com/w3c/csswg-drafts/issues/913 for more info on this issue.

konrad
  • 1,664
  • 2
  • 17
  • 36
2

In my case, the problem was caused by mixing a css transform with overflow: auto; on the parent.

I created a new child element on which I moved the overflow property.

Separating the two properties fixed the issue.

Etienne Martin
  • 10,018
  • 3
  • 35
  • 47
-3

It's a mobile specific issue. I have encountered this issue before. Generally speaking mobile browsers, particularly older ones, restrict the use of fixed positioning because it can take up too much room on the screen.

http://bradfrost.com/blog/mobile/fixed-position/

partypete25
  • 4,353
  • 1
  • 17
  • 16
  • I got this issue using Google Chrome on device emulation mode for iPhone 6 (it happens with all other devices on google chrome too), but thanks, i'll check this link! – Luiz Mitidiero Apr 26 '16 at 05:06
  • The article referred to was posted in 2011. Even when this answer was posted in 2016 it was outdated. Yes there are still mobile browsers out there that can't handle it (very old and Opera Mini in particular) but Opera Mini and other such users must be used to a pretty broken experience on the wild web. Check out caniuse.com for current (and historic, to some extent) situation. – Nick Rice Jul 05 '17 at 11:52
  • 1
    i don't know why you got so down voted. my "high-tech" iPhone + last iOS chrome can't handle a `position:fixed;` properly and i'm looking for solution everywhere, nothing solid found. Yes we are in 2018. – Laurent Feb 15 '18 at 01:46