5

it's a known 'bug' that elements with fixed position loose their position if the container is translated. For example, if i've got a structure like this:

<div class="container">
   <div class="fixed"></div>
</div>

and, say, the container is scrolled, when the conteiner gets transformed (say, translate(x,y), rotate(), or so..), then the fixed element behaves like it was positioned relative and it scrolls with the container. I can see it on the latest firefox, for example.

How can one fix this kind of problem? Is there any way?

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118

3 Answers3

2

This behaviour is not a bug. It's actually the specs recommended behaviour.
(See this post by Eric Meyer, or this question here on SO which accepted solution only provides a link to the same meyer's post)

For those who don't know this issue, and because you didn't provide a snippet into your question, here's one.

document.addEventListener('click', function() {
  document.getElementById('container').classList.toggle('transformed')
}, false);
#bg {
  border: 1px solid #AFA;
  height: 100%;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
}
#container {
  border: 1px solid #FAF;
  height: 50%;
  width: 75%;
  position: relative;
  margin: 0 auto;
  overflow: auto;
}
#content {
  background: rgba(125, 175, 0, .7);
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
}
.transformed {
  transform: translate(0, 5em);
}
<div id="bg">
  <div id="container" class="transformed">
    .<br>.<br>.<br>.<br>.<br>.<br>.
    this is a scrollable paragraph
    <br>.<br>the "fixed" content does scroll with the paragraph
    <br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
    you can click to toggle the transformation On/Off
    <br>.<br>.<br>.<br>.<br>.
    <span id="content">relatively fixed content</span>
  </div>
</div>

However, I did find something that may help others facing the same issue.
It's not really a solution, since the "fixed" element will be only inside the container, (except for IE browsers where it will really be fixed to the document). But in my case, it's actually what I wanted and maybe it'll be fine for others too.

If you add a wrapper, set its height:100%; width:100%; and overflow:auto, then your "fixed" content won't scroll with the container.

Actually it's not you container which scrolls anymore, but the wrapper. So you might want to set the container's overflow:visible or hidden to avoid unwanted scrolling of the not so well "fixed" element.
Also, note that you need your wrapper be a block or inline-block element.

#bg {
  border: 1px solid #AFA;
  height: 100%;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
}
#container {
  border: 1px solid #FAF;
  height: 50%;
  width: 75%;
  position: relative;
  margin: 0 auto;
  overflow: visible;
}
#wrapper {
  height: 100%;
  width: 100%;
  overflow: auto;
}
#content {
  background: rgba(125, 175, 0, .7);
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
}
.transformed {
  transform: translate(0, 50%);
}
<div id="bg">
  <div id="container" class="transformed">
    <div id="wrapper">
      .<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
      <span id="content">relatively fixed content</span>
    </div>
  </div>
</div>
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0

I am not familiar with this bug, but when you use positioned: fixed; the element is positioned relative to the browser window, so it doesn't really make any sense to put it inside a container. This markup would be my recommendation:

<div class="fixed"></div>
<div class="container"></div>
JimmyRare
  • 3,958
  • 2
  • 20
  • 23
  • not always. My case is that of an header bar that must scroll with the container only till a certain amount, than a part of it is setted fixed. The container is also absolute positioned. You know, that kind of things. Being building also an off-canvas on the same page, I need to use translate3D on the container. – Luca Reghellin Oct 31 '14 at 20:53
-1

Once you use position: fixed; on any element it is positioned relative to the view-port. Directly from page in MDN about position property.

fixed
Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and don't move it when scrolled.

So what you are experiencing is a what it is actually supposed to work like and not a 'bug'.

Now if what you want is something that is positioned with relation to the .container div and translate with it than you will have to use absolute positioning here. Take a look at this fiddle. The important CSS is-

.container {
  width: 200px;
  height: 100px;
  position: relative;
}
.absolute {
  position: absolute;
  width: 20px;
  height: 10px;
  top: 50px;
  left: 50px;
}

Notice that with positioning the inner div as absolute I have also positioned the outer div as relative as the inner div takes its position in reference to the closest parent div positioned as anything different from static.

vabhdman
  • 191
  • 2
  • 6
  • Hi, thank you but that's not exactly my case, see my comment above. I know fixed elements should stay out, but this is an hybrid one (it changes). So I need a fixed element inside a [positioned+scrolled+translated] element, and the fixed one must be always fixed as it should. – Luca Reghellin Oct 31 '14 at 20:57
  • So when you say hybrid do you mean that it should be positioned normally for some part and position fixed after a certain part ? Please explain this in a little detail because once you use `fixed` on anything it doesn't matter what you do with the parent container. – vabhdman Oct 31 '14 at 21:19