Reputation: 9489
is there a way to auto adjust container DIV height to accommodate absolutely positioned child DIVs? i'd like to get something like
+-----------------------+ | container | | +------+ +------+ | | | chld | | chld | | | | 1 | | 2 | | | | | | | | | +------+ +------+ | | +------+ | | | chld | | | | 3 | | | | | | | +------+ | +-----------------------+
i try something like:
<div class="container" style="position: relative; border: solid thin">
<div class="chld" style="width: 20px;
height: 20px;
position: absolute; left: 5px; top: 5px;
border: dashed thin;"><div>
<div class="chld" style="width: 20px;
height: 20px;
position: absolute; left: 30px; top: 5px;
border: dashed thin;"><div>
<div class="chld" style="width: 20px;
height: 20px;
position: absolute; left: 15px; top: 30px;
border: dashed thin;"></div>
</div>
but the "container" div stays zero height. I understand, that this might be the expected behaviour, as elements are 'taken out' of the flow when positioned absolutely, but is there a workaround for this? (except for precalculating the resulting height and setting it manually)
Upvotes: 30
Views: 65052
Reputation: 23500
If you use position:relative instead of position absolute an empty space will stay in the page structure where the element should be, and this space will be the height of the element you've moved.
So you could float chld1 and chld2 to get them side by side, add top & bottom padding to push chld 3 down and use position relative to split them apart and move to any height. Then use clear both on chld3.
Something like
#exp_outer {
width: 400px;
border: 1px solid black;
}
#chld1 {
float: left;
margin: 30px 0 20px;
left: 50px
}
#chld2 {
float: right;
margin: 30px 0 20px;
right: 50px;
}
#chld3 {
left: 150px;
clear: both;
}
.box {
position: relative;
width: 80px;
height: 80px;
border: 1px solid black;
}
<div id="exp_outer">
<div id="chld1" class="box">Child1</div>
<div id="chld2" class="box">Child2</div>
<div id="chld3" class="box">Child3</div>
</div>
Upvotes: 9
Reputation: 1983
I couldn't find any simple pure-javascript workaround for this little problem, so here it comes (you need to add id fields to your html code):
var containerBox = document.getElementById('container');
var statBoxBottom = document.getElementById('chld3').getBoundingClientRect().bottom + window.scrollY;
var mainDivBottom = containerBox.getBoundingClientRect().bottom + window.scrollY;
var boxHeightDiff = statBoxBottom - mainDivBottom;
if (boxHeightDiff > 0)
containerBox.style.height = Math.ceil( containerBox.offsetHeight + boxHeightDiff ) + 'px';
It basically increases "container" height based on absolute bottom position of "chld3".
Upvotes: 0
Reputation: 364
I've troubled quite a lot to achieve this and now that i have a solution it looks like it would have been so simple, anyway, some jQuery/Javascript is needed:
jQuery(window).load(function(){
var valueCheck = [];
jQuery('.projectsWrap .hentry').each(function(){
var itemObj = jQuery(this);
var itemValues = itemObj.position();
var top = itemValues.top;
var height = jQuery(this).height();
var sum = top + height;
valueCheck.push(sum);
});
var res = Math.max.apply(Math, valueCheck);
jQuery('.projectsWrap').height(res);
});
I wrote and implemented this little script in a WordPress theme hence you see the "$" are converted to "jQuery" for compatibility but if you are not using WordPress you should revert them back to "$".
The situation i was in was even more difficult than the one in the question because the user wanted to autonomously absolutely position each element in the container and the order in which elements appeared in the dom was not related to their position in the container: totally unexpectable results (first element in the dom may appear as last bottom element in the window for example).
Also the heights of elements were all different, all different heights and all different top values (offset), a nightmare.
What the script does is get the height and top value of each element, sum them and put this sum in an array, the array is then checked to find the biggest value, this value is the height the container will be set to, magic!
Upvotes: 0
Reputation: 124
overflow:auto
This is the new clearfix method, FYI. However, it doesn't always expand the container to the height of its tallest & absolutely positioned child.
Upvotes: 10
Reputation: 9489
i ended up using clearfix, this allows me to set the desired width of the container, and it's height will be adjusted automatically, depending on the contents (this works in all browsers)
<style>
.inner_box {
position: relative;
float: left;
width: 50px;
height: 50px;
border: dashed thin;
margin: 5px 5px 5px;
text-align: center;
}
.outer_box {
position: relative;
top: 200px;
border: solid thin;
width: 190px;
//height: 1%;
}
.outer_box:after {
content: '.';
display: block;
clear: both;
visibility: hidden;
height: 0;
line-height: 0;
}
</style>
<div class="outer_box">
<div class="inner_box">1</div>
<div class="inner_box">2</div>
<div class="inner_box">3</div>
<div class="inner_box">4</div>
<div class="inner_box">5</div>
<div class="inner_box">6</div>
</div>
Upvotes: 4
Reputation: 11431
No. The whole idea is that absolutely positioned element does not influence its parent layout.
Try achieving your goal by relatively positioning floats instead of absolute positioning of divs. It is not as convenient (because of starting position of your floats is not ass 0,0) but it will work.
Upvotes: 2
Reputation: 23
If you give the .container div a height of 100% it should calculate it from the child elements in most browsers but unfortunately not IE6 or lower.
Upvotes: -6