There is a rendering issue with Google Chrome and Opera (why?=) with such code:
<html>
<style>
#content {
width: 150px;
background: gray;
}
#sidebar {
position: fixed;
left: 200px;
background: gray;
}
</style>
<body>
<div id="sidebar">
<a href="#s1">Link #1</a><br/>
<a href="#s2">Link #2</a>
</div>
<div id="content">
<div id="s1">
<a href="#s1">Link #1 TARGET</a>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.</p>
</div>
<div id="s2">
<a href="#s2">Link #2 TARGET</a>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
</div>
<a href="#">TOP</a>
</body>
</html>
As you can see, I am trying to make sidebar static on the right side.
Everything works fine, until you add some <UL>
tag on the page:
http://www.youtube.com/watch?v=zkhH6di2M0c
The fixed div sometimes starts to disappear when I click anchor links.
What can be done to avoid such behavior?
It makes sense if you understand how Normal Flow of the document works. Let's say it's an edge case scenario.
There is no height declared in any element and #sidebar is taken OUT of the normal flow of the document by being
position:fixed
.If you add a height property to #sidebar (pixels, not percentages) the problem is solved.
I would suggest including Normalize.css, I think it will take care of the bug.
Chrome solution:
Adding
-webkit-transform: translateZ(0)
to the#sidebar
fixed the issue for me.I've used
translateZ(0)
to fix numerous Chrome display bugs over the years. The rationale is that by invoking 3D transformation, re-paint is separated from the rest of the CSS pain stack (I can't provide much more detail than that, it's pretty much all Greek to me). In any case, it appears to work for me!Opera solution:
This is not a generic solution (will need to be tweaked depending on the positioning requirements of the element in question). It works by forcing continuous repaints (via CSS animation) on a property that could affect layout (forcing other layout factors to be calculated and rendered, ie maintaining fixed positioning), but in practice do not. In this case, I've used
margin-bottom
, because there's no way that's going to affect your page layout (but Opera doesn't know that!):Note: the solution is not perfect, in that (on my machine at least) the bug test cases will result in a minute flicker as Opera loses positioning and quickly redraws. Sadly I think this is as good as you will get, because as George says in his answer, this is Opera's natural behaviour between redraws — in theory my code makes redraw for the element continuous, but in practice there will be infinitesimal gaps.
EDIT 2 (2013-11-05): I've since encountered variations of this bug quite often. Although the original poster's reduced test case presents a perfectly legitimate bug, most occurences have been in situations where there is already a 3D transform operating on the body (or similarly high up the DOM tree). This is often used as a hack to force GPU rendering, but will actually lead to nasty repaint issues like this. 2 no-op 3D transforms don't make a right: if you're using one higher up the tree, try removing it first before adding another one.
EDIT 3 (2014-12-19): Chris reports that
translateZ(0)
doesn't work in some cases wherescale3d(1,1,1)
does.The key for Chrome is:
By adding this, the fixed position problem should be fixed.