views:

2806

answers:

8
+3  Q: 

DIV collapsing!

I have a few nested divs:

<div id="wrapper">
  <div id="header">
    <!-- a bunch of float divs here -->
  </div>

  <div id="body">
    <div id="content">
      <!-- a bunch of html controls here -->
    </div>
  </div>
</div>
  • wrapper style: width: 780px; margin: 20px auto; border: solid black 5px;
  • header style: position: relative; min-height: 125px;
  • body style: position: relative;
  • content style: position: absolute; left: 50px; top: 0px;

I have a bunch of html elements in the content div and for some reason the body div and the wrapper div are collapsing around the header and the content div hangs out on its own if I don't set a fixed height for the body div. The only float elements I have are in the header.

EDIT:

If I remove the content div (and drop the html elements directly in body) the body div stops collapsing! Trying to understand why - guess it's due to the position: absolute of the content div.

Any clue why this is happening and how to solve?

I had a look at this question but It doesn't seem to work for me (or maybe I am clearing inthe wrong place...).

A: 

Try clearing after your floated elements within the header.

<div id="wrapper">
  <div id="header">
    <!-- a bunch of float divs here -->
    <div style="clear:both;"></div> <!-- Or use a clearfix... -->
  </div>

  <div id="body">
    <div id="content">
      <!-- a bunch of html controls here -->
    </div>
  </div>
</div>

As long as the clearing element is within the containing div it should accomplish what you want.

Zack Mulgrew
A: 

Add style "clear: both" to your div with "body" id. You could also add a div with this style just after "bunch of float divs" and before closing tag of header div.

Stiropor
Adding clear:both to the body div will only position the body div in the correct place, but the header div will still be collapsed because its contents are not in normal flow.
Zack Mulgrew
A: 

When you want to clear something you also need to float that element to make it work properly. So you will need.

#header { clear: both; float: left; }
#body { clear: both; float: left; }
Alex
+1  A: 

I use this style for clearing elements:

.Clear { clear: both; height: 0; overflow: hidden; }

Place a clearing div in the header, to give the header element size:

<div id="wrapper">
  <div id="header">
    <!-- a bunch of float divs here -->
    <div class="Clear"></div>
  </div>

  <div id="body">
    <div id="content">
      <!-- a bunch of html controls here -->
    </div>
  </div>
</div>

Setting the height of the clearing element to zero causes it to take up no space by itself. The overflow style is so that IE will not give it a height eventhough the height is set to zero. IE has a strange idea that every element has to be at least one character high, setting overflow:hidden; keeps the height at zero eventhough the content of the element is one character high in IE.

Guffa
A: 

I'm not a fan of using "clear:both" if it's not totally needed. A better solution is setting the "overflow" property of the collapsing DIV to "auto".

Try something like:

#header { float: left; overflow: auto; }
Allan
This doesn't work in ie6
Alex
+2  A: 

Try this. Note: the overflow hidden on the header div solves the need for a clearing div. Note sure why you're using relative+absolute positioning for the content though. That's better handled with margins imho.

<html>
<head>
  <title>Layout</title>
  <style type="text/css">
    #wrapper { width: 780px; margin: 20px auto; border: solid black 5px; }
    #header { overflow: hidden; background-color: yellow; }
    #header div { float: right; border: 2px solid red; }
    #body { position: relative; }
    #content { position: absolute; left: 50px; top: 0px;  }
  </style>
</head>
<body>
    <div id="wrapper">
      <div id="header">
        <div>One</div>
      <div>Two</div>
      <div>Three</div>
      </div>
      <div id="body">
     <div id="content">
       <p>This is some text</p>
     </div>
      </div>
    </div>
</body>
</html>
cletus
+1  A: 

If you want #content to show up within the border boundaries of #wrapper try this swap on for size, after you remove position:relative from #body (or remove that DIV entirely):

#header{position: relative; overflow:hidden; clear:both;}
#content{position:relative; left:50px; top:0px;}

That way you will be able to see #content show up within the wrapper but beneath #header.

May be happening because there really isn't anything for #content to stick out from under. #header, when it was set to relative, kind of disappears for the below, even if #body was then set to absolute with descendants of it set to relative.

Changing up #content from position:absolute to position:relative will have it come under the previous DIV, which in this case was #header.

random
Thanks - position:relative on #content kind of works (without removing the #body div, I need it!)
JohnIdol
+2  A: 

You don't really need to use absolute or relative positioning in this case.

The following achieves what you need with a minimal amount of css wrangling.
Colours becuase I like colour, and so should you!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html>
 <head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  <title>Page Title</title>
  <style type="text/css" media="screen">
 #wrapper { 
  width: 780px; 
  margin: 20px auto; 
  border: solid black 5px;

 }
    #header { 
     min-height: 125px; 
     overflow:hidden;

 }
    #body { 
     background-color:red; 

 }
    #content { 
     margin-left: 50px;
     margin-top: 0px;
     background-color:pink; 

  }
.floatie { float:left; width:40px; height :40px; 
 margin:5px; background-color:#fe0;}

  </style>


 </head>
 <body>



  <div id="wrapper">
    <div id="header">
    <div class="floatie"></div>
    <div class="floatie"></div>
    <div class="floatie"></div>
    <div class="floatie"></div>
    <div class="floatie"></div>
    <div class="floatie"></div>
    <div class="floatie"></div>
    </div>

    <div id="body">
      <div id="content">

    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
     sed do eiusmod tempor incididunt ut labore et dolore 
     magna aliqua. Ut enim ad minim veniam, quis nostrud 
     exercitation ullamco laboris nisi ut aliquip ex ea 
     commodo consequat. Duis aute irure dolor in 
     reprehenderit in voluptate velit esse cillum dolore eu 
     fugiat nulla pariatur. Excepteur sint occaecat 
     cupidatat non proident, sunt in culpa qui officia 
     deserunt mollit anim id est laborum.</p>
      </div>
    </div>
  </div>

 </body>
</html>
garrow
Your orphan FORM tag is showing
random
fixed extraneous form tag! thanks for that... (reusing sample code FTW!)
garrow