views:

270

answers:

1

Is "absolute" absolute or not?

I am trying to make an input form with nested elements, each containing other elements, but it does not display correctly (according to a screen ruler (and the naked eye)).

The HTML is valid, so is this a case of "well, it's absolute, but only relative to it's containing folder" or some such?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>
<head>
<title></title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
</head>
<body>
<form action="C:\temp\an_elogger_test.php" method="get"><div class="TGroupBox" id="GroupBox1">
<fieldset style="position: absolute; top:24px; left:24px; width: 449px; height: 473px;">
<legend>GroupBox1</legend>
<div class="TPanel" id="Panel1">
<fieldset style="position: absolute; top:64px; left:64px; width: 361px; height: 217px;">
<legend></legend>
<div class="TComboBox" id="ComboBox1" style="position: absolute; top:88px; left: 256px; width: 145px; height: 21px;">
  <select name="ComboBox1">
    <option value="- one -" selected="selected">- one -</option>
    <option value="- two -">- two -</option>
    <option value="- three -">- three -</option>
</select>
</div>
<div class="TGroupBox" id="GroupBox2">
<fieldset style="position: absolute; top:80px; left:88px; width: 145px; height: 177px;">
<legend>GroupBox2</legend>
<div class="TCheckBox" id="CheckBox1" style="position: absolute; top:112px; left: 104px; width: 97px; height: 17px;">CheckBox1<input type="checkbox" name="CheckBox1" value="CheckBox1Checked"></div>
<div class="TCheckBox" id="CheckBox2" style="position: absolute; top:152px; left: 112px; width: 97px; height: 17px;">CheckBox2<input type="checkbox" name="CheckBox2" value="CheckBox2Checked"checked="checked"></div>
</fieldset>
</div>
<div class="TRadioGroup" id="RadioGroup2">
<fieldset style="position: absolute; top:128px; left: 264px; width: 145px; height: 137px;"><legend>RadioGroup2</legend>

eins: <input type="radio" name="RadioGroup2" value="eins" checked><br>

zwei: <input type="radio" name="RadioGroup2" value="zwei"><br>

drei: <input type="radio" name="RadioGroup2" value="drei"><br>
</fieldset>
</div>
</fieldset>
</div>
<div class="TMemo" id="Memo1"><textarea name="Memo1" rows="8" cols="13" style="position: absolute; top:320px; left: 88px; width: 185px; height: 89px;">
</textarea>
</div>
<div class="TComboBox" id="ComboBox2" style="position: absolute; top:328px; left: 296px; width: 145px; height: 21px;">
  <select name="ComboBox2">
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    <option value="d" selected="selected">d</option>
    <option value="e">e</option>
</select>
</div>
</fieldset>
</div>
<div class="TPanel" id="Panel2">
<fieldset style="position: absolute; top:32px; left:520px; width: 425px; height: 449px;">
<legend></legend>
<div class="TPanel" id="Panel3">
<fieldset style="position: absolute; top:64px; left:552px; width: 345px; height: 185px;">
<legend></legend>
<div class="TMemo" id="Memo2"><textarea name="Memo2" rows="8" cols="13" style="position: absolute; top:88px; left: 584px; width: 185px; height: 89px;">
You may wish to leave this memo emptyOr perpahaps give instructions aboout what should be written here</textarea>
</div>
<div class="TEdit" id="Edit1" style="position: absolute; top:200px; left: 600px; width: 121px; height: 21px;"><input type="text" name="Edit1"value="Insert text here"></div>
</fieldset>
</div>
<div class="TGroupBox" id="GroupBox3">
<fieldset style="position: absolute; top:272px; left:552px; width: 345px; height: 185px;">
<legend>GroupBox3</legend>
<div class="TPanel" id="Panel4">
<fieldset style="position: absolute; top:304px; left:584px; width: 177px; height: 137px;">
<legend></legend>
<div class="TRadioGroup" id="RadioGroup1">
<fieldset style="position: absolute; top:312px; left: 600px; width: 97px; height: 105px;"><legend>RadioGroup1</legend>

one: <input type="radio" name="RadioGroup1" value="one"><br>

two: <input type="radio" name="RadioGroup1" value="two" checked><br>

three: <input type="radio" name="RadioGroup1" value="three"><br>
</fieldset>
</div>
</fieldset>
</div>
<div class="TEdit" id="Edit2" style="position: absolute; top:320px; left: 776px; width: 105px; height: 21px;"><input type="text" name="Edit2"></div>
</fieldset>
</div>
</fieldset>
</div>
</form>
</body>
</html>
+5  A: 

"absolute" means absolute, relative to he nearest "relative parent". A relative parent is either an element with position:relative or, if there isn't one, the document.

Additionally, making an element absolute has certain implications, like removing it from document flow. The DOM will be laid out as if the absolute elements do not exist. This means containers will not wrap around absolute elements and no elements will be pushed out of the way by them.

CSS positioning can seem like black magic until it is revealed that it follows these very simple rules - no exceptions! (which is a good thing)

Edit: The specifics of what you do here depend on what you are trying to accomplish. Why are you using absolute positioning in the first place? Absolute positioning has the simplest rules, but is also very powerful, and powerful tools are also a lot harder and require a lot more manual work, and they have more potential for bad things to happen. That's the trade-off. For example, if one element grows larger without moving the other ones to take that into account, they could overlap. Absolute positioning depends on you keeping values in proportion on each element to make sure they are all lined up correctly. And if you want a wrapping element, it requires that you always update the height and width properties to keep it large enough to have the appearance of wrapping.

To take advantage of what document flow provides - wrapping, automatic alignment, etc - you can use floating, margins and padding. Based on my limited understanding of what you are trying to do here, I would set the padding of the container fieldset to reflect where the child fields should be positioned and give each field a margin. For fields that should sit to the right of the previous instead of the next line, use float:left and clear:left.

Rex M
Also, good to mention that if you do want absolute positioning (as in absolute to the window) then use `position: fixed;`
Duracell
+1: Good insight. Thanks!
DavidR
relative, absolute and fixed, it's all good, but what's your goal? I see that your code set absolute for all elements... Can you provide an image of your goal? Because I do believe that you can get what you want with far less css :)
Zuul
I wish I could allocate the answer to a comment, because `position: fixed;` works for me. I could leave it here, but I want to ask Rex (who gets the answer) ... 1) how should I do this 'properly'? I have no element marked `position:relative`, so shouldn't my code, where everything is absolute just display as if it were fixed? It does not. 2) If I mark everything as fixed, will I still get wrap problems? How to do it best? Perhaps mark the fieldsets as relative and the rest as absolute? but - what about nested fieldsets?
Mawg
Sorry, I'm not subscribed to any image sharing service, but if you take the HTML and replace absolute with "fixed" throughout, it will look very close to what I want. There are still a few anomalies, though
Mawg
@mawg I am pretty sure `fixed` is not what you want, because being absolute relative to the window, not the document, means that if the document is long enough to be scrolled, the document will scroll but the fixed elements will not move.
Rex M
@mawg see my updated answer.
Rex M