6

Suppose you have a parent div that contains several normal children and one absolute child.

I've read practically everywhere that a child with position: absolute will not influence parent's height, since it is out of the normal flow. However in my case, an absolute element expands the parent, and I can't understand why.

(I tried reading the spec but I'm really lost.)

HTML

<div class="container">
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="outsider"></div>
</div>

CSS

.container {
  overflow: hidden;
}

.block, .outsider {
  width: 100%;
  height: 1000px;
}

.block {
  background: red;
}

.outsider {
  position: absolute;
  left: 0;
  top: 3000px;
  background: green;
  opacity: 0.5;
}

CSS overflow

Why does the browser let me scroll past the element's supposed height? It seems consistent in Chrome, Safari and Firefox so I presume it's part of the spec.

How do I prevent this behavior? I'd like absolutely positioned element to be cropped if it doesn't fit into the container height “dictated” by “normal” children.

See it live.

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • The **body** probably has some default padding/margin. – Paulie_D May 08 '14 at 11:55
  • My coworker suggested I try `position: relative` on the container, and it worked. For the love of G-d, I can't figure out *why*. – Dan Abramov May 08 '14 at 11:56
  • Because without it the absolute position will be relative to the body and positioning `left` will refer to viewport and ignore padding/margin? _ http://codepen.io/Paulie-D/pen/aexbz – Paulie_D May 08 '14 at 11:57

1 Answers1

4

You are missing a position on your parent container. Add

.container{
     position: relative;
}

The absolutely positioned element will go back up the DOM to find the nearest positioned parent, in this case you don't have one explicitly defined, so it's going back up to <body>

JesseEarley
  • 1,036
  • 9
  • 20
  • 1
    This works but I still don't understand **why it expands its container's height**. Do you think you could explain it? – Dan Abramov May 08 '14 at 12:08
  • 3
    It's not expanding the containers height, as you don't have an explicit height set on .container. Since .outsider is being positioned in accordance with body and not .container, you're scrolling the body, not the container, which is why you're able to see .outsider. – JesseEarley May 08 '14 at 12:12
  • That completely makes sense. Thank you! – Dan Abramov May 08 '14 at 12:39
  • 1
    From the MDN docs, "Absolutely positioned element is removed from the normal document flow; no space is created for the element in the page layout". By this logic, no extra space should be added for `outsider` in the above example, and hence there should not be any scroll bar. So what am I missing here? – darKnight Nov 08 '17 at 07:15
  • 1
    My guess is that absolutely positioned elements will always expand the body tag's height or width regardless of parent having `position: relative;` if the `overflow: hidden;` is missing. At least that's the effect I see. – Terry Feb 16 '21 at 15:33
  • in chrome, I did not see calculated body height get larger, but there was a scroll bar indeed – wang eason Nov 12 '21 at 02:34