tags:

views:

209

answers:

1

There is an inner div of fixed width and variable height contained by an outer div. The inner div should have a 5px margin on all 4 sides between it and the outer div.

How can this be achieved if the height of inner div is not specified?

With the height of the inner div specified this is very simple. But the inner div is a content container for a masterpage. The content going into this div will have a different height for each page that uses the master page.

If the inner divs height is not set, the bottom margin (between where the inner div ends and the outer div ends) is always 2-3px too long. i.e. 5 5 5 8 This happens across browser types.

Here is the CSS:

#contentframe
{
    position: relative;
    width: 1010px;
    left: 0px;
    top: 0px;
    margin: 0px;
    padding-top:5px;
    padding-bottom:5px;
    padding-left: 14px;
}
#content
{
    position: relative;
    left: 0px;
    top: 0px;
    width: 980px;
    margin: 0px;
    padding: 0px;
    background-color: #cccccc;

}

* Note: Setting margin-bottom of #content to 5px does not work.

HTML:

    <div id="contentframe">
        <div id="content">
            variable height content will go in here
        </div>
    </div>

This should be dead simple. Set: Outer divs padding to 5px and that's it. But that only works if inner divs height is specified. Otherwise there is an annoyingly "high" bottom margin.

EDIT: Full Source

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head id="Head1" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css"> 
body
{
    -x-system-font: none;
    background-color: #A2A2A2;
    margin-top: 0px;
    margin-bottom: 35px;
    padding: 0px;
}
#centeredframe
{
    width: 1010px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 0px;
    padding: 0px;
}

#contentframe
{
    position: relative;
    width: 1010px;
    left: 0px;
    top: 0px;
    margin: 0px;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 5px;
    background-color: #ffffff;
}

#content
{
    position: relative;
    left: 0px;
    top: 0px;
    width: 1005px;
    margin: 0px;
    padding: 0px;
    height:300px;
    color: #ffffff;
    background-color: #000000;
}

</style>
</head>
<body>
    <div id="centeredframe">
        <div id="contentframe">
            <div id="content">
                <p>hgjghjghjghjg<p>
                <p>hgjghjghjghjg<p>
                <p>hgjghjghjghjg<p>
                <p>hgjghjghjghjg<p>
            </div>
        </div>
    </div>
</body>
</html>
+2  A: 

This should work on IE7/8 and other non-IE browsers.

The extra 'padding/margin' to the top and/or bottom is introduced by the <p> elements. This is due to the uncollapsing margin for empty-content/padding/border areas (in this case, the contentFrame). Refer to the W3C Box Model on collapsing margins.

There are a few ways around it, one of which is to introduce a thin (1px) border which blends into the background of the DIV and then compensating with the width/height. Below is another hack by manipulating the margin/padding of the <P> element within the content DIV.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head id="Head1" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css"> 
body
{
    -x-system-font: none;
    background-color: #A2A2A2;
    margin: 0;
    margin-bottom: 35px;
    padding: 0px;
}
#centeredframe
{
    width: 1010px;
    margin: 0 auto; /* merged */
    padding: 0;
}

#contentframe
{
    width: 1000px;
    margin: 0;
    padding: 5px;
    background-color: #ffffff;
}
#content
{
    padding: 0;
    color: #ffffff;
    background-color: #000000;
    height: auto;
    min-height: 300px;
}
#content p
{
    margin: 0px; /* removed the default margin of p element*/
    padding: 16px 0; /* replaced with padding to have background*/
}
</style>
</head>
<body>
    <div id="centeredframe">
        <div id="contentframe">
            <div id="content">
                <p>hgjghjghjghjg</p>
                <p>hgjghjghjghjg</p>
                <p>hgjghjghjghjg</p>
                <p>hgjghjghjghjg</p>
            </div>
        </div>
    </div>
</body>
</html>
o.k.w
There is actually a background image for outer div that puts a nice fade around the outer divs border. The padding-left:14px is there to achieve the desired 5px offset for the inner div. i.e. 9px of fade the 5px of #ffffff. If i set bottom:5px then what will that be registered against? The outer div does not have a set height, I want it to stretch to a height of 5px top offset + inner div height (variable) + 5 px.
rism
In that case, you can adjust the top, right, left, and bottom values for the content div to suit your need.
o.k.w
O.k, so I tried your suggestion but that just increases the differential. i.e. 5 5 5 12.
rism
Are you able to see where the 12px are accounted for? E.g. using Firebug's HTML layout tool. It could be due to an additional padding somewhere in the child element of the content OR the content div itself. Try setting the paddings to zero. Btw, the 12 is for the left, isn't that what you want?
o.k.w
Sorry I meant 5 5 12 5
rism
No. I cant find anything using Firebug to account for the offset. Ive added a full source file above if that makes things easier.
rism
Based on your codes, the I only see a wider gap on top. Try the new one in my updated answer, you should get consistent white 5px border around the black content DIV.
o.k.w
Yeah, weird now the gap is at the top. I've tried your code and it works but only because there is a specified height in #contentframe. Take that out and the frame doesn't show at all. So back to square one.
rism
BTW - Thanks for your efforts. I cant believe it's this elusive.
rism
It's not elusive. The remaining issue is the height. Do you need a minimum height? Or a flexible one depending on the content within the content div?
o.k.w
I need the height to scale depending on the pages content. It would never be less than 300px but it could be any height greater than that.
rism
Ok, check out my updated (again) answer. The extra gap you encountered earlier is caused by the margin of the `<p>` which somehow reveals the white background of the contentFrame. I've used a trick to overcome it, see my CSS comments. Another way to overcome that is to add another layer of DIV within the content but that becomes quite untidy. Your original codes did not close the `<p>` properly, you might want to correct it.
o.k.w
Brilliant. So it was the <p> element that was causing the hassle. Maybe I should start another question about this but I thought the inner div would expand its height to account for this. If <p> is contained by <div> then why didn't <div> grow to accommodate <p>?
rism
I thought so too, hahah. Go ahead and start another question on this, what I did was to hack around this issue. I'm curious to know the actual reason as well.
o.k.w
I found the reason for the mystery, see my updated (one last time) answer. :)
o.k.w
Great thanks for the additional info. I knew about the way <p>'s stack but I've never hit this specific problem before :)
rism