Intive Blog

The betrayal of position: fixed

There are few certain things in life. The poles north-south, which side a toast with jam will fall on, or whether Lost after the second season was a hoax.

Those of us who work in front-end, particularly with CSS, although we are used to overlapping things, we do it because we are actually sure that every single thing will do what it always does.

Hence, if I want something to have a behavior or appearance, I only have to define that behavior or appearance. And if I want to change that afterwards, it will overlap by simply defining the property again. This is the cascade effect. The last steps on the first.

But on some occasions, this is not so. And the world as we know it falls apart.

In one of our recent projects, we implemented a third party package that allows us to display a contextual menu. We followed the suggested steps for the implementation, but it did not work. However, we did not receive any error of any kind.

When inspecting the DOM in our application, we saw that the contextual menu was actually there, but it was not being displayed. One of the properties of that menu was position: fixed. Let us remember that this property ensures that an element will be displayed in a given place or viewpoint or screen (to say it simply). That is, all which have position:fixed will be in a place and nothing else matters.

And you may very well think: “Hey, a position:fixed is not hidden just like that.”

And you could not be more right. But here the mystery does begin.

In a parent element, we modified through JS the property translate3d in order to scroll an element in an animation.

After some research, we found other poor victims of this anomaly, same as us.

Question in StackOverflow

After reading the specification, we learnt that any element that uses translate or translate3d, converts all the position: fixed; of their children elements in position:relative, but this ‘absolute’ is relative to his parent element.
You see, suddenly the north is the south and so on.

Transform rendering

As proper nerds, we decided to test it. Here is a fiddle: https://jsfiddle.net/a2dtsgag/5/

As you can see, if the position:fixed of the second element worked, we would only see an orange square, since both would overlap, however, we can see two. All thanks to that damned translate. Try it. You can delete the property of its parent element and you will immediately see that both orange squares overlap.

The property translate3d, which is the one we were using, accepts 3 parameters.

One refers to the horizontal scroll, another to the vertical and the last zooms in or out the element. It is like making it come out of the screen or sinking it.

Luckily for us, we were only using translate for a horizontal scroll, so we could replace translate(value, 0, 0) with left: value or right: -value, and that was it.
If we had used translate for a vertical scroll, we could have used top:value; or bottom: value;.

But if we had had to use the third property…

OK, let us better not think in those obscure scenarios.

It is us.

Pablo Hiyano

Pablo Hiyano is coordinator of technical teams at intive-FDV. A student of Biology at Universidad de Buenos Aires (UBA), since kid his great interest in programming made him a self-taught developer passionate for the Javascript world. In his free time, he enjoys playing with his child, watching british series and reading about philosophy, especially works by Michel Foucault.

Sebastián Bogado

He was a full stack developer at intive – FDV. He worked with the Javascript stack on many platforms (Smart TVs & Smartwatches, NodeJS, hybrid mobile apps, and -of course- the browser).

Add comment