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.
After reading the specification, we learnt that any element that uses
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.
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.
translate3d, which is the one we were using, accepts 3 parameters.
translate3d(value, value, value)
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
But if we had had to use the third property…
OK, let us better not think in those obscure scenarios.
It is us.