How can I constrain the width of an absolutely positioned nested div?
I have a complicated multi-level menu. The (absolutely positioned) right hand menu items are spilling out of the (absolu开发者_如何学Ctely positioned) container in IE and Opera, but not in Firefox (or Chrome or Safari); I suspect that Firefox is wrong because I don't see why an absolutely positioned element should have its dimensions constrained by an absolutely positioned ancestor. However, it is the Firefox effect that I am trying to achieve.
My constraints are: I know the width of .outer
; however, I don't know the content (and therefore width) of any of the spans which should determine the width of .middle
. I don't know the content (and therefore width) of any of the .inner
divs, however, their width must not affect the width of the parent .middle
. The left hand edge of .inner
must line up with the left hand edge of it's sibling span. Ie, it's a two-level menu, whereby the 2nd level must be constrained within an ancester's border, but each item in the first level must not be affected by the width of its child menu.
What changes to I need to make to constrain the inner div to the boundaries of the outer div in IE? See a simplified version of the code below. In the original markup, .outer
was a ul
and .middle
was a li
.
<head>
<style type="text/css">
*{
margin: 0;
padding: 0;
list-style-type: none;
}
.outer{
border: solid 1px black;
width: 200px;
position: absolute;
}
.outer div
{
border: solid 1px green;
float: left;
}
.inner
{
position: absolute;
}
.inner p
{
border: solid 1px red;
}
span{
display: block;
padding: 0 10px;
}
.hide
{
display: none;
}
</style>
</head>
<body>
<div class="outer">
<div class="middle">
<span>outer</span>
<div class="hide"><p>lots and lots of inner text</p></div>
</div>
<div class="middle">
<span>outer</span>
<div class="hide"><p>lots and lots of inner text</p></div>
</div>
<div class="middle">
<span>outer</span>
<div class="inner"><p>lots and lots of inner text</p></div>
</div>
</div>
</body>
You can do this by setting .inner
to position: relative
. It's not evident from your code sample why you selected absolute
in the first place, but any manual positioning you want to do should be achievable with relative
. Instead of setting the top
, right
, bottom
, or left
properties relative to the origin of its containing block, set them relative to where .inner
would normally be positioned in the flow.
Hope that helps!
I think actually Firefox is correct, but I'm no CSS expert. According to w3schools, the default implementation should allow content to render outside of the containing box if it's too wide for it.
It depends what you want the overflowing content to do. Have you tried setting the overflow
CSS property on your outer DIVs? Or set the width
on the inner DIVs?
I have found a partial solution, applying position relative to .middle
. This should be applied to IE. Unfortunately, this messes around with the padding, but hopefully this will be a smaller issue to fix. This version is using the correct elements - not just divs.
<head>
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
list-style-type: none;
}
.outer{
border: solid 1px black;
position: absolute;
width: 200px;
}
.inner
{
position: absolute;
width: auto;
}
.middle
{
border: solid 1px green;
float: left;
}
.inner *
{
border: solid 1px red;
}
span{
display: block;
}
.hide
{
display: none;
}
</style>
<!--[if IE]>
<style type="text/css">
.middle{
position: relative;
}
</style>
<![endif]-->
</head>
<body>
<ul class="outer">
<li class="middle">
<span>outer</span>
<ul class="hide"><li>lots and lots of inner text</li></ul>
</li>
<li class="middle">
<span>outer</span>
<ul class="hide"><li>lots and lots of inner text</li></ul>
</li>
<li class="middle">
<span>outer</span>
<ul class="inner"><li>lots and lots of inner text</li></ul>
</li>
</ul>
</body>
精彩评论