/    Sign up×
Community /Pin to ProfileBookmark

Dynamically Positioning Objects

Hi All,

I’m trying to figure out how to dynamically position objects without resorting to javascript and I’m stumped. Fixed position, fixed length, no problem but as soon as the lengths of divs becomes dynamic, I’m lost.

For reference, take a look at [URL=”http://www.thirdepoch.com”]www.thirdepoch.com[/URL]. Don’t bother looking at the html. It’s just the layout I’m interested in. (The html was generated by a WYSIWYG web designer merely as a visual reference and the html on the live site will be created by my own cms on the fly.)

What I’m trying to do is dynamically position the divs on the page. If you look at the boxes in the middle, you’ll see there’s a large one, followed by two smaller ones, and that pattern is repeated. My problem is these boxes are generated on the fly so I don’t know their lengths before they’re drawn.

Clearly, the two smaller ones need to be drawn the same length, which adds another layer of complication.

I’m guessing a combination of position:relative and position:absolute is going to do the work, but can someone point me in the right direction please.

Note that the footer block is dynamically positioned using javascript to check the length of the left block (where the menu is) and the centre block. The problem with this method is that javascript can only extract the size of the innermost div.

Also note that I’ve also thought about abandoning divs and going back to a table structure but I don’t think that’s the way forward.

Any suggestion is, as always, much appreciated.
Thanks
CTB

to post a comment
CSS

8 Comments(s)

Copy linkTweet thisAlerts:
@KorApr 27.2011 — You could use the [B]float[/B] and [B]clear[/B] CSS properties. Horizontal centering can be achieved using the left and right margins as [B]auto[/B]. Do you need an example?
Copy linkTweet thisAlerts:
@chestertbauthorMay 01.2011 — Hi Kor,

Thanks for the response. Yes Please. An example would be useful.

Cheers

CTB
Copy linkTweet thisAlerts:
@chestertbauthorMay 01.2011 — I have discovered that getting the height of an element relies on two things. The first is obvious and the second rather obscure.

The first is that getting the height successfully depends on when it's requested, so it needs to be requested after the page is drawn. Yes. Obvious I know, but doing that when the page loads need care.

The second is that IE fails to give you the measurement of a div if there are elements within it.

The work around is to set the width and overflow.

style='width:500px; overflow:auto'

Having said that, it still doesn't seem to work with complex layouts, but it's a start.

Any more light on this would be useful.
Copy linkTweet thisAlerts:
@KorMay 02.2011 — Hi Kor,

Thanks for the response. Yes Please. An example would be useful.

Cheers

CTB[/QUOTE]

OK, here's a basic example of using float and margin to create a simple layout:
<i>
</i>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Untitled Document&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
&lt;meta http-equiv="Content-Style-Type" content="text/css"&gt;
&lt;meta http-equiv="Content-Script-Type" content="text/javascript"&gt;

&lt;style type="text/css"&gt;
*{
margin:0;
padding:0
}
#main{
width:900px;
margin:0 auto 0 auto;
}
#header{
width:100%;
height:80px;
background:#9CC
}
#content{
min-height:500px;
}
#content .side_left{
float:left;
width:20%;
background:#FC9;
min-height:500px;
}
#content .side_right{
float:left;
width:20%;
background:#6CF;
min-height:500px;
}
#content .center{
float:left;
width:60%;
min-height:500px;
}
#content .clear{
clear:both;
}
#footer{
width:100%;
height:80px;
background:#9CC
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="main"&gt;
&lt;div id="header"&gt;header
&lt;/div&gt;

<i> </i>&lt;div id="content"&gt;
<i> </i> &lt;div class="side_left"&gt;left
<i> </i> &lt;/div&gt;
<i> </i> &lt;div class="center"&gt;center
<i> </i> &lt;/div&gt;
<i> </i> &lt;div class="side_right"&gt;right
<i> </i> &lt;/div&gt;
<i> </i> &lt;div class="clear"&gt;&lt;/div&gt;
<i> </i>&lt;/div&gt;

<i> </i>&lt;div id="footer"&gt;footer
<i> </i>&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
Copy linkTweet thisAlerts:
@chestertbauthorMay 05.2011 — Thanks Kor.

Much appreciated.

However, what happens when the content that goes inside 'center' is complex?

I have a layout that places several divs in the same location (with each shown or hidden by a button), a sub-navigation panel down the side, and three parts of a form, also in the same location and also selected by buttons.

The positioning of all of that is currently fine, though to achieve it, I needed to place divs within divs. It's all wrapped in a single div I call 'container' with a div called 'footer' coming after that.

My problem is in the footer. It just doesn't want to find its way to the bottom of the page because offsetHeight and clientHeight can't seem to get the height of an element (in this case 'center') that contains lots of other elements.

Any pointers you might be able to give will be very much appreciated.

CTB
Copy linkTweet thisAlerts:
@KorMay 05.2011 — Not very clear, but I guess you have encountered the famous layout problem in case of floating elements.

If a container nests floated elements, his layout will not follow the vertical sum of the heights of those elements, unless you make it to. For instance:
<i>
</i>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Untitled Document&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
&lt;meta http-equiv="Content-Style-Type" content="text/css"&gt;
&lt;meta http-equiv="Content-Script-Type" content="text/javascript"&gt;
&lt;style type="text/css"&gt;
*{
margin:0;
padding:0;
}
#container{
width:500px;
margin: 40px auto 0 auto;
border:solid 1px #ff0000;
}
.inner_l, .inner_r{
width:200px;
height:200px;
background:#CCC;
}
.inner_l{
float:left;
}
.inner_r{
float:right;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="container"&gt;
&lt;div class="inner_l"&gt;&lt;/div&gt;
&lt;div class="inner_r"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

There are several way to solve this problem. A simple one is to force the container's layout on adding, at the end of the row of the floated elements, an empty div [I]out of the float[/I] ("cleared")
<i>
</i>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Untitled Document&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
&lt;meta http-equiv="Content-Style-Type" content="text/css"&gt;
&lt;meta http-equiv="Content-Script-Type" content="text/javascript"&gt;
&lt;style type="text/css"&gt;
*{
margin:0;
padding:0;
}
#container{
width:500px;
margin: 40px auto 0 auto;
border:solid 1px #ff0000;
}
.inner_l, .inner_r{
width:200px;
height:200px;
background:#CCC;
}
.inner_l{
float:left;
}
.inner_r{
float:right;
}
[COLOR="Blue"].clear{
clear:both;
}[/COLOR]
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="container"&gt;
&lt;div class="inner_l"&gt;&lt;/div&gt;
&lt;div class="inner_r"&gt;&lt;/div&gt;
[COLOR="Blue"] &lt;div class="clear"&gt;&lt;/div&gt;[/COLOR]
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;


Is this your problem? The container loses its layout because the elements inside are floated?
Copy linkTweet thisAlerts:
@chestertbauthorMay 05.2011 — Kor,

You have been a HUGE help. Thank you thank you!

Of course, it means I'll have to completely redesign my pages, but hey... I should have dont things right in the first place. :-)

I took your original code and worked on it a little to give me what I need (see below). The only issue I have left is the vertical positioning of the images within the header. I've tried vertical-align with height:100% but that doesn't work. However, I already calculate the heights of the three images so I'll just give them a top value and move on.

Thanks again.

Here's the html...

[code=html]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled Document
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
*{ margin:0; padding:0 }
*#main{ width:900px; margin:0 auto 0 auto; }
*#header{ width:100%; vertical-align:middle; background:#9CC }
*#header .hleft{float:left; width:33%; height:100%; text-align:left}
*#header .hcenter{float:left; width:34%; height:100%; text-align:center; background:#DCDCDC;}
*#header .hright{float:left; width:33%; height:100%; text-align:right}
*#header .reset{ clear:both; }

*#separator{ width:100%; height:20px; background:#7B4F33 }
*#content{position:relative; min-height:500px; }
*#content .side_left{ float:left; width:20%; background:#FC9; min-height:500px; }
*#content .side_right{ float:left; width:20%; background:#6CF; min-height:500px; }
*#content .center{ float:left; width:60%; min-height:500px; }
*#content .clear{ clear:both; }
*#footer{ width:100%; height:80px; background:#9CC }
</style>
</head>
<body>
<div id="main">
<div id="header">
<div class='hleft'>
<img src='/images/image1.jpg'>
</div>
<div class='hcenter'>
<img src='/images/image2.jpg'>
</div>
<div class='hright'>
<img src='/images/image3.jpg'>
</div>

<div class="reset">
</div>
</div>
<div id='separator'>
</div>
<div id="content">
<div class="side_left">left

</div>
<div class="center">
<div style='float:left; height:300px; width:200px; border:1px solid black'>
</div>
<div style='float:left; height:300px; width:200px; border:1px solid black'>
<div id='a' style='position:relative; top:10px; left:10px; height:100px; width:100px; background:#000000; display:none'>
<p style='color:#ffffff'>Control</p>
</div>
<div id='b' style='position:relative; top:10px; left:10px; height:100px; width:100px; background:#6C6C6C; display:none'>
<p style='color:#ffffff'>Option</p>
</div>
<div id='c' style='position:relative; top:10px; left:10px; height:100px; width:100px; background:#ffffff; display:block'>
</div>
<div style='position:relative; left:10px; top:20px'>
<p><a href="javascript:show('a')">[Show Black]</a></p>
<p><a href="javascript:show('b')">[Show Grey]</a></p>
</div>

</div>
<div class="clear">
</div>
<div style='position:relative; height:600px; width:100%; border:1px solid black''>
</div>
</div>
<div class="side_right">right
</div>
<div class="clear">
</div>
</div>
<div id="footer">footer
</div>
</div>
<!--
<div style="position:fixed; top:150px; left:300px; height:400px; width:600px; background:#2c2d2e; border:1px solid black; display:none">
</div> -->
</body>
<script type='text/javascript'>
function show(z)
{
document.getElementById('c').style.display = 'none';
document.getElementById('b').style.display = 'none';
document.getElementById('a').style.display = 'none';

document.getElementById('z').style.display = 'block';
}
</script>
</html>[/code]
Copy linkTweet thisAlerts:
@KorMay 06.2011 — Vertically centering is quite a tricky mission in CSS 2. For a text is easy: simply set for the parent a [B]line-height[/B] equal with its [B]height[/B]. For an image, even it is an inline element that won't work, as in fact the bottom of the image is align on middle, not the center of the image. Moreover, in fact the bottom of the image is a little bit lower, as the possible text around the image is the subject of the line-height.

There are some intricate solutions for that, of course. But my advice is to calculate exactly the distances and to use margin-top (or margin-bottom) to place the element exactly in the middle, vertically, of its parent.
×

Success!

Help @chestertb spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.6,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...