Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to retain fixed positions of elements inside transformed elements?

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?

like image 872
Luca Reghellin Avatar asked Nov 09 '22 23:11

Luca Reghellin


1 Answers

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>
like image 101
Kaiido Avatar answered Nov 14 '22 23:11

Kaiido