Search code examples
htmlcsspositionheightabsolute

Position: absolute and parent height?


I have some containers and their children are only absolute / relatively positioned. How to set the container's height so their children will be inside of them?

Here's the code:

HTML

<section id="foo">
  <header>Foo</header>

  <article>
    <div class="one"></div>
    <div class="two"></div>
  </article>
</section>    
    
<div style="clear:both">Clear won't do.</div>
<!-- I want to have a gap between sections here -->
    
<section id="bar">
  <header>bar</header>
  
  <article>
    <div class="one"></div>

    <div></div>

    <div class="two"></div>
  </article>
</section>  

CSS

article {
  position: relative;
}
    
.one {
  position: absolute;
  top: 10px;
  left: 10px;
  background: red;
  width: 30px;
  height: 30px;
}
    
.two {
  position: absolute;
  top: 10px;
  right: 10px;
  background: blue;
  width: 30px;
  height: 30px;
}

Here's a jsfiddle. I want the "bar" text to appear between 4 squares, not behind them.

http://jsfiddle.net/Ht9Qy/

Any easy fixes?

Note that I don't know the height of these children, and I can't set height: xxx for containers.


Solution

  • 2022 UPDATE. This answer is nearly 10 years old. When it was written we didn't have layout technologies like Flex or Grid available (they were dark, hacky/fun times).

    Thankfully things have massively improved. Jöcker's answer shows you how to achieve this layout with Grid. If you can live with not supporting legacy browsers, do that instead!


    Original Answer

    If I understand what you're trying to do correctly, then I don't think this is possible with CSS while keeping the children absolutely positioned.

    Absolutely positioned elements are completely removed from the document flow, and thus their dimensions cannot alter the dimensions of their parents.

    If you really had to achieve this affect while keeping the children as position: absolute, you could do so with JavaScript by finding the height of the absolutely positioned children after they have rendered, and using that to set the height of the parent.

    Alternatively, just use float: left/float:right and margins to get the same positioning effect while keeping the children in the document flow, you can then use overflow: hidden on the parent (or any other clearfix technique) to cause its height to expand to that of its children.

    article {
      position: relative;
      overflow: hidden;
    }
        
    .one {
      position: relative;
      float: left;
      margin-top: 10px;
      margin-left: 10px;
      background: red;
      width: 30px;
      height: 30px;
    }
        
    .two {
      position: relative;
      float: right;
      margin-top: 10px;
      margin-right: 10px;
      background: blue;
      width: 30px;
      height: 30px;
    }