Search code examples
htmlcss

Fixed element positioning relative to its parent


I have an element that gets position: fixed while dragging. This element is inside a modal that is a direct child of the body element.

On the image below, the modal is gray, the rest of the body is black, and the button is blue. When I add the following styles to the button:

position: fixed;
top: xxxpx;
left: -100px;

It positions the button relative to the modal, not the viewport. Is that even possible that an element with position: fixed be positioned relative to something but the viewport? It acts like an absolutely positioned element instead.

enter image description here


Solution

  • 'normally' position fixed fixes relative to the viewport.

    But there are exceptions. See MDN

    The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none (see the CSS Transforms Spec), in which case that ancestor behaves as the containing block. (Note that there are browser inconsistencies with perspective and filter contributing to containing block formation.) Its final position is determined by the values of top, right, bottom, and left.

    Here's a simple example:

    body {}
    
    .parent {
      position: relative;
      margin: 100px;
      transform: scale(1);
      width: 50vw;
      height: 10vw;
      background: black;
      rfilter: blur(1);
    }
    
    .child {
      position: fixed;
      top: 0px;
      left: 0px;
      width: 100px;
      height: 100px;
      background-color: blue;
    }
    <body>
      <div class="parent">
        <div class="child"></div>
      </div>
    </body>

    Notice that the blue child element is placed at the top left of its parent. Its parent has a transform - and as it's scale(1) we might assume it doesn't do much. But it does create the parent as the containing block.

    I think your problem is the transform on the parent.