The uncanny relationship between position fixed and transform property.
Tags: css, css3, webdev
Published: 2021-06-05 09:10:37

**TL;DR**
> An element with `position:fixed` is positioned relative to the document (the viewport) which acts as its containing block. 

> But, it will NOT always be relative to the document. When any element has `transform`, `filter` or `perspective` property, it acts as a containing block for all its descendants, including the elements whose position is set to fixed.  

## Now, the long story...

While I was working on enhancing the navigation bar of the 
[Polygon Wallet](https://wallet.matic.network/), I found myself stuck with a strange error. I spent almost a day trying to figure out the issue, consulted with the senior frontend engineers and also thought of making a separate Vue component as a workaround. 

When I finally found the bug, I wouldn't shy away to say that my ego went crashing down, as it was a CSS bug, and my CSS skills are something I take pride in.

I was doing some changes to the code to align the dropdown menus to the cente of the navigation item (as shown in the picture below) for which I had to move the *dropdown component* inside the `<li>`. Doing this would allow me to use the CSS position and transform properties to align the dropdown exactly at the bottom-center of the navigation item. 

![Dropdown menu opens at the center](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2296vua8gbirmcmwr6z6.gif)

Till now, everything was working fine and nothing was unusual and unexpected. 

Inside the dropdown menu, there were a bunch of notification items, which when clicked would open the modal component. 

The components were nested something like this
```html
<li>
  <span>Notifications</span>

  <dropdown-menu>
    <item>
      <modal />
    </item>

    <item>
      <modal />
    </item>
  </dropdown-menu>
</li>
```

The *modal component*, which was supposed to open at the center of the screen when clicked on the item, would just behave weirdly and open inside the dropdown menu itself. I was sure that, **any element with a fixed position would ignore all its ancestors and position itself relative to the document (the viewport or the root element)**. But that just didn't happen. The ancestor element, in this case, the *dropdown menu* was acting as a containing block for the *modal component*.

![Modal opens in a weird way](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71u1ovgzttyu8mlydkqa.gif)

And as you might have guessed, it was due to the transform property. **Any element with `transform`, `filter` or `perspective` property will act as a containing block to all its descendants, including the elements whose position is set to fixed.** Hence the modal, instead of positioning itself with respect to the document, positioned itself relative to the dropdown-menu component where I had used the transform property to align it exactly at the bottom-center of the navigation item. See [CSS Transform Spec](https://www.w3.org/TR/css-transforms-1/#propdef-transform)


## How did I fix it?
Well, there is no fix for that, I just removed the transform property, gave a fixed width to all the dropdown components and achieved the same result with the help of the margin and position properties. *But this uncanny relationship between position and transform property reminded me why CSS takes the crown as my favorite language even when I have a multi-paradigm language like JavaScript in my stack.* ❤

![Modal opens as expected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5htlp2bylacit5y92vm.gif)

**Thank you!**

If you want to learn about CSS positions, refer to
[CSS Tricks](https://css-tricks.com/almanac/properties/p/position/)
[MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/position)