77

When scrolling on a website I've built, using the CSS property position: fixed works as expected to keep a navigation bar at the very top of the page.

In Chrome, however, if you use the links in the navigation bar it sometimes disappears. Usually, the item you've clicked on is still visible, but not always. Sometimes the entire thing disappears. Moving the mouse around brings back part of the element, and scrolling with the scroll wheel or arrow keys just one click brings the element back. You can see it happening (intermittently) on https://nikeplusphp.charanj.it - you might have to click on a few of the navigation the links a few times to see it happen.

I've also tried playing with the z-index and the visibility/display type but with no luck.

I came across this question but the fix didn't work for me at all. Seems to be a webkit issue as IE and Firefox work just fine.

Is this a known issue or is there a fix to keep fixed elements visible?

Update:

Only effects elements that have top: 0;, I tried bottom: 0; and that works as expected.

cchana
  • 4,899
  • 3
  • 33
  • 43
  • I wonder whether it's related to [this issue](http://code.google.com/p/chromium/issues/detail?id=95338)... – raina77ow Jun 29 '12 at 09:15
  • Thanks for the link, I've contributed to the thread, but still wondering if there's a way around the issue. – cchana Jun 29 '12 at 10:00
  • Funny, I have the exact opposite problem where `top:0` displays the element but `bottom:0` does not. Unfortunately none of these answers fix it either. – CodingWithSpike Jun 12 '15 at 14:10
  • Just a side note, your page is trying to load unsafe scripts (HTTP protocol) while the normal protocol for your page is HTTPS. You should probably fix that as it's a security issue, and major browsers (like chrome) won't load the scripts initially, which can break your page – FullyHumanProgrammer Jan 25 '16 at 15:27
  • @FullyHumanProgrammer thanks, this question was posted long before I switched to HTTPS but looks like something has changed. Will look into it. – cchana Jan 25 '16 at 15:28

13 Answers13

207

Add -webkit-transform: translateZ(0) to the position: fixed element. This forces Chrome to use hardware acceleration to continuously paint the fixed element and avoid this bizarre behavior.

I created a Chrome bug for this https://bugs.chromium.org/p/chromium/issues/detail?id=288747. Please star it so this can get some attention.

Cœur
  • 37,241
  • 25
  • 195
  • 267
TJ VanToll
  • 12,584
  • 4
  • 43
  • 45
  • 5
    I struggled with this bug for several hours, you saved me. This should be the accepted answer! Thanks. – Jan Peša Jan 15 '14 at 13:51
  • 1
    This worked for me, I had the problem only on Chrome/Win, not on Chromium/Ubuntu, by the way. – Paolo Mioni Jan 24 '14 at 11:52
  • Came here from google after days of going mental over this issue. I thought it was some of my badly written javascript causing the issue in my case, but this fixed everything. Thankyou so much! – ESR Jan 29 '14 at 22:34
  • 1
    I actually had this same issue occurring with an absolutely positioned element, and this also fixed that. – BronzeGate Mar 26 '14 at 14:55
  • Thanks, you made my day! I suppose this bug is related to stacking contexts. In Chrome 22 the layout behavior of position:fixed elements is slightly different than previous versions. All position:fixed elements now form new stacking contexts. http://updates.html5rocks.com/2012/09/Stacking-Changes-Coming-to-position-fixed-elements – Konstantine Kalbazov Apr 16 '14 at 14:14
  • I couldn't use this solution because I was relying on z-index values for the element and its parent. Removing the parent z-index value solved it for me though. – koosa May 04 '14 at 13:23
  • This fix also works, when a parent has `position:relative` and his children may partially disappear on page refresh. Thank you and rays of... well, surprise to Chrome =) – bonflash May 12 '14 at 08:43
  • Just about one year after this answer and I still ran into the same issue in Chrome 37 on Mac with a site I'm working on. Thanks for this answer. It was driving me crazy that it happened in Chrome, but not in Firefox! Boo-urns to the Chrome team for not fixing this yet! – MindJuice Sep 04 '14 at 05:14
  • 2
    Bug is still there in Chrome38/OSX and this answer still works. – tobiv Nov 12 '14 at 01:45
  • 2
    Found this problem, Chrome 41.0.2224.3 the answer solved the problem. Thanks! – Diego Sucaria Nov 21 '14 at 02:00
  • This bug still seems to be present in Chrome Version 46.0.2490.71 (64-bit). Anyways, this fix worked for me and saved me hours.. thanks! – Still Questioning Oct 25 '15 at 05:03
  • @TJ VanToll: it works, but not at all for me. I've got this problem with a bootstrap navigationbar ` – Tenaciousd93 Nov 25 '15 at 08:18
  • I spent hours on this issue. I was working on a CSS only Fixed Header Solution that worked great in all Browsers except Chrome... adding this line fixed the issue. Thanks! – Jordan Jan 21 '16 at 18:59
  • 1
    Interesting, this did not solve it for me. Chrome Version 48.0.2564.82 (64-bit), Mac OS X Yosemite 10.10.3) – Charlie-Greenman Jan 27 '16 at 20:33
  • Interesting - this DID work for me (even though my version was very similar to @Razroo-Chief): Chrome Version 48.0.2564.116 (64-bit), Mac OS X Mavericks 10.9.2. I was also working on a fixed header solution. – Brian Feb 25 '16 at 00:50
  • unfortunately, it does not work for me on Chrome 48.0.2564.116 on ubuntu :( – Angel M. Mar 02 '16 at 16:36
  • This fix worked for me on Chrome 50.0.2661.102 (64-bit) OSX but now once scrolled the elements underneath receive the hover and click interactions. Anyone else encountered this issue? – yo.ian.g May 25 '16 at 16:45
  • Switching from translateZ to translate3d fixed the issue I just mentioned above! – yo.ian.g May 25 '16 at 17:16
  • 3
    That moment when a perfect answer makes you wonder just what you would have done if stackoverflow did not exist! – Jeph Feb 04 '18 at 17:24
  • How has it been so many years and this is still a bug, thanks for the answer! – ricks Jun 19 '18 at 13:31
49

This fixes it for me:

html, body {height:100%;overflow:auto}
Cooper
  • 549
  • 4
  • 7
  • 1
    That is a very uncomfortable question to ask agaisnst a code base of millions of lines...but hey it works!!!!! THANKS – Asad Hasan Jul 08 '14 at 22:01
  • Above answer did not work for me, but this did. Thank you :) – Charlie-Greenman Jan 27 '16 at 20:34
  • This fixed it for me. I've had this issue many times, and usually it's fixed by this. It only happens on a real device and every time it makes me wonder if it's something with the swipe. – Christian Jun 30 '16 at 10:44
  • this fixed it for me, while @TJ VanToll's answer doesn't – abidibo Jun 19 '17 at 09:57
  • I am using absolute elements, and they disappear randomly showing white boxes where they should be (their space is preserved but they appear as white area!) once you click any of them (even if not a clickable element) they re-appear! so it seems to be a rendering problem of some sort! I am still testing after adding this, but I think it worked for those absolute elements too! they now render properly, no white spaces (at least yet). I have no idea why this helped either! been struggling for a while with this! Thank you!! – Khaled Nov 20 '17 at 18:18
  • I was also facing the problem with fixed elements on Chrome, I thought it was JS-connected, because the fixed elements were disappearing on slide transition, but it actually solved the problem.... weird!!! `overflow:auto` was enough for me. – Dandy Nov 22 '17 at 16:33
  • 1
    This made the fixed div stop moving with the mobile url bar for me, but then messed up other parts of the page, namely it disrupted my JS on scroll listener – auto Feb 21 '18 at 18:56
19

I was having the same issue with Chrome, it seems to be a bug that occurs when there is too much going on inside the page, I was able to fix it by adding the following transform code to the fixed position element, (transform: translateZ(0);-webkit-transform: translateZ(0);) that forces the browser to use hardware acceleration to access the device’s graphical processing unit (GPU) to make pixels fly. Web applications, on the other hand, run in the context of the browser, which lets the software do most (if not all) of the rendering, resulting in less horsepower for transitions. But the Web has been catching up, and most browser vendors now provide graphical hardware acceleration by means of particular CSS rules.

Using -webkit-transform: translate3d(0,0,0); will kick the GPU into action for the CSS transitions, making them smoother (higher FPS).

Note: translate3d(0,0,0) does nothing in terms of what you see. it moves the object by 0px in x,y and z axis. It's only a technique to force the hardware acceleration.

#element {
    position: fixed;
    background: white;
    border-bottom: 2px solid #eaeaea;
    width: 100%;
    left: 0;
    top: 0;
    z-index: 9994;
    height: 80px;
    /* MAGIC HAPPENS HERE */
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
}
Neo
  • 11,078
  • 2
  • 68
  • 79
8

The options above were not working for me until I mixed two of the solutions provided.

By adding the following to the fixed element, it worked. Basically z-index was also needed for me:

-webkit-transform: translateZ(0);
z-index: 1000;
cortopy
  • 2,758
  • 2
  • 25
  • 31
  • 1
    This solution worked for me today. Chrome 45 came out and my site had a (position: fixed) issue. Adding the (-webkit-transform: translateZ(0) seems to have fixed it. (I'm aware of the z-index, too, but my site already has a z-index set for the afflicted elements.) – Jerome P Mrozak Sep 03 '15 at 20:49
  • `-webkit-transform: translateZ(0);` did it for me. Didn't need to use z-index. – Marco Roy Jan 05 '17 at 22:23
2

This is a webkit issue that has yet to be resolved, oddly making the jump with JavaScript, rather than using the # url value, doesn't cause the problem. To overcome the issue, I supplied a JavaScript version that takes the anchor value and finds the absolute position of the element with that ID and jump to that:

var elements = document.getElementsByTagName('a');
for(var i = 1; i < elements.length; i++) {
    elements[i].onclick = function() {
        var hash = this.hash.substr(1),
            elementTop = document.getElementById(hash).offsetTop;
        window.scrollTo(0, elementTop + 125);
        window.location.hash = '';
        return false;
    }
}

I could refine this further and make it is that only it only looks for links beginning with a #, rather than ever a tag it finds.

cchana
  • 4,899
  • 3
  • 33
  • 43
2

If it don't work after adding

-webkit-transform: translateZ(0)

than also add

user-scalable=no

on viewport meta

source here

it worked for me

Community
  • 1
  • 1
1

I encountered the same issue in a different case. It was because of usage of same id in multiple place. For example i used #full 2 divs.

It seems that mozilla and I.E. supports usage of same id in multiple cases. But chrome doesnot. It reacted with fixed element disappering in my case.

Just removing the id's solved the problem.

Ritesh Jung Thapa
  • 1,177
  • 2
  • 13
  • 20
1

None of them worked for me except calling the modal via javascript

<a href="#\" onclick="show_modal();">Click me to open MyModal</a>
<script>
function show_modal()
{
  MyModal.style.display = 'block';
}
</script>

other than this, none of the solutions above solved my problem.

maslan
  • 46
  • 3
1

This Worked for me . Add Overflow property to your top most container which can be Div or Form etc.

div, form
{
  overflow:visible;    
}
kumar chandraketu
  • 2,232
  • 2
  • 20
  • 25
1

The same issue happened to me. For the main page of the website. I made a fixed header and Used an image for the front poster. Everything worked fine. But the moment I changed the opacity of the poster image my header with position: fixed; got disappeared. It was present there in the chrome developer tools. But was totally transparent on the website.

I tried every solution from StackOverflow, W3shools, Geeke4geeks. But if one thing was fixed another thing got messed up.

So I just opened photoshop and edited the image manually. And then posted it on my website. It worked. But still, it won't be effective for divs under the fixed elements.

amit.exe
  • 81
  • 1
  • 2
0

If none of the answers above worked for you, make sure you aren't a dummy like me and have overflow: hidden; set on the fixed element :(

0

What if none of above worked at all? simple case of sticky header + mobile side menu pushing content.

I try to find a way to avoid fixed element (sticky header) being translated but in this case nothing is a good alternative.

So as there is no workaround on scope so far there is a JS alternative that I opted for to recalculate absolute position of fixed element. See here: https://stackoverflow.com/a/21487975/2012407

Community
  • 1
  • 1
antoni
  • 5,001
  • 1
  • 35
  • 44
0

In my case, I just added min-height: 100vh; to fixed element, may be that will be useful for somebody