konrad
konrad

Reputation: 1724

Why adding transform to fixed parent changes child width?

I have a fixed child div inside fixed parent div. When I set the child width to 100% it is set either to 100% width of the window OR 100% of the parent width if I add transform: translate to the parent div.

parent div css:

#outer {
  position: fixed;
  top: 0;
  left: 50%;
  // transform: translate(-50%, 0);

  width: 400px;
  height: 200px;
  z-index: 5000;
  background-color: red;
}

child div:

#inner {
  position: fixed;
  width: 100%;
  left: 30%;
  top: 20%;
  background-color: green;
}

Now #inner is 100% width of the screen. Uncommenting the transform line makes it 100% of parent. What's going on?

  1. http://codepen.io/kokojr/pen/wWvbrz
  2. http://codepen.io/kokojr/pen/KMKLQX

UPDATE:

  1. Ok, I didn't notice that at first but actually it's not only width that changes, position becomes relative too.

  2. For anyone who wonders, that works down the way as well. If you add an #inner-inner div with fixed position it will position itself rel. to #outer unless you add a transform to #inner as well. It's #inner then that becomes the context for fixed children. Reminds me of this very interesting article: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/

Upvotes: 6

Views: 670

Answers (1)

Oriol
Oriol

Reputation: 288120

From CSS 2.1 - Definition of "containing block" and CSS Position 3 - Definition of containing block,

If the element has position: fixed, the containing block is established by the viewport in the case of continuous media or the page area in the case of paged media.

However, that changes when you add transforms to some ancestor. From CSS Transforms 1 - The Transform Rendering Model,

For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.

Upvotes: 5

Related Questions