Forum Moderators: not2easy

Message Too Old, No Replies

dhtml / nested divs bug in FF?

Parent div doesn't redraw if nested div's content is modified

         

chiefthunder

11:49 pm on May 1, 2005 (gmt 0)

10+ Year Member



Hello masters,

I have a div, with an image inside positioned at the div's bottom. Also inside the div there's a second div which I want to fill with content:

<DIV STYLE="position:absolute; left:50px; top:50px; width:40%; background:grey;">
<DIV ID=CONTENT>abc</DIV>
<IMG STYLE="position:absolute; left:0px; bottom:0px; />
</DIV>

now when I use scripting to modify the contents of the inner div, e.g.:

el = document.getElementById('content');
el.innerHTML = "abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />";

shouldn't this push the image down as the parent div gets larger together with the innerdiv?

It does so in IE, but in FF the image stays where it is.

The problem seems to be that the inner div (id=content) doesn't notify it's parent that it has been resized: When I modify the size of the browser a little bit, the image jumps down immediately.

This is probably a known bug, I couldn't find any information on it though. Is there maybe any known workaround for this?

Btw if I use span in place of the inner div, it works. This is not an option though.

Thanks very much in advance for any replies, I've been racking my brains for several hours on this.

ps: here's a copy paste test page


<html>
<head>
<script>
function test() {
el = document.getElementById('content');
el.innerHTML = "abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />";
}
</script>
</head>
<body>
<div style="position:absolute; left:50px; top:50px; width:40%; background:grey;">
<img style="position:absolute;left:0px; bottom:0px" src="rsrc03.gif">
<DIV id=content>abc def<BR />ghi jkl</DIV>
</div>
<a onclick="javascript:test()">click here to test</a>
</body>
</html>

Stormfx

4:43 am on May 2, 2005 (gmt 0)

10+ Year Member



It works in IE cause IE doesn't fully support standards. The reason it doesn't work in Firefox is because the DIVs are absolutely positioned. When they're positioned in that manner, they become like 'layers' and are not affected by any changes around them. To get it to work the way you're implying, try using this:

<div style="position:relative; left:50px; top:50px; width:40%; background:grey;">
<DIV id=content>abc def<BR />ghi jkl</DIV>
<img style="position:relative;left:0px; bottom:0px" src="rsrc03.gif">
</div>

This does sort of the same thing, but positions it relative to its current position. It also allows the item to be affected by changes in nearby elements, as it is positioned relative to those items.

Also note that the image is moved down below the DIV tag. That's if you want the image at the bottom. It will appear on the page where it is in the code.

Hope that helps :D

chiefthunder

9:49 am on May 2, 2005 (gmt 0)

10+ Year Member



Thanks, I understand :)
Still I think, since absolute positioned elements get positioned relative to their parent elements, wouldn't it make sense if this relation would be kept when the parent element changes?.
I mean, it works that way when the parent is resized by changing the browser windows size for example (presumed size given in %)
Not by DHtml changes though. I think this is an inconsistency.
It's also weird that the image jumps back to it's parent's bottom once I resize the browser window only a tiny bit. I think it's a bug.

Stormfx

4:38 pm on May 2, 2005 (gmt 0)

10+ Year Member



Only relative positioned elements are affected by other elements. Absolute positioned elements are positioned based on the actual browser window, without any reguards to any other elements.

As far as relative changes go, it totally depends on the cirumstance. For example, if the DHMTL actually changes the inheritancy & an element's parents are changed, it will inherit the attributes of the new parent. However, if it doesn't affect the inheritance, like the example above, then it will affect the surrounding elements as expected.

See what I mean?

chiefthunder

11:59 am on May 3, 2005 (gmt 0)

10+ Year Member



Hmm not quite. I still think that "absolute" positioned elements get positioned relative to their parent's border, not necessarily the main browser window.

If that border changes (by whatever means - dhtml or as a result from resizing the main browser window), I think the element placement should change as well.

I checked w3 for the standards, but it seems scripting changes are not fully covered by them.

It works btw when I set the parent's positioning to relative, and then quickly back to absolute. e.g.

parent= document.getElementById('idparent');
parent.style.position = relative;
parent.style.position = absolute;

This refreshes the element and everything jumps into place. It flickers a little though. Maybe there are any other workarounds?

Btw, I can't use relative positioning because the element should not occupy any space in the parent's div.

Cheers,
Ct

createErrorMsg

12:43 pm on May 3, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I still think that "absolute" positioned elements get positioned relative to their parent's border, not necessarily the main browser window.

Absolute positioning removes the element from the document flow, and then places it at your pixel coordinates, relative to the nearest positioned container, or the viewport if no positioned containers are present.

But once placed, that element is out of the flow. Your observation that briefly setting the position value to relative and then back to absolute works because as soon as it becomes a relative element, it is back in the flow. It then takes a position from it's source location, then when you set it back to position absolute, it is again removed from the flow and placed where you want it.

I can't use relative positioning because the element should not occupy any space in the parent's div.

If this is the case, then you might try setting it as a background image on the container...

background: url(path/to/image.gif) left bottom no-repeat;

To clear the text away from the image, simply set a bottom margin equal to the height of the image on the #content div.

Here's the test page (based off of your own). Works identically in IE6/Win and FF...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script>
function test() {
el = document.getElementById('content');
el.innerHTML = "abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />abc<BR />";
}
</script>
<style type="text/css">
#box{
position:absolute;
left:50px;
top:50px;
width:40%;
background:#ccc url(path/to/image.gif) left bottom no-repeat;
}
#content{
margin-bottom:35px; /*equal to height of image*/
}
</style>
</head>
<body>
<div id="box">
<div id="content">abc def<BR />ghi jkl</DIV>
</div>
<a onclick="javascript:test()">click here to test</a>
</body>
</html>

cEM

chiefthunder

2:23 pm on May 3, 2005 (gmt 0)

10+ Year Member



Thanks for that cem. Unfortunately BG images are also not an option since I'd like to have the actual image outside the Div.

Actually, what I want is to have a fancy frame around my Div, consisting of 8 images: 4 "corner" images and 4 "side" images that will get stretched to the height/width of the Div.

I've done this with tables recently, but would prefer to do it using 100% css.

I understand btw that the element is "out of the flow" but I'm still convinced it should stick to the border of the containing Div if this is resized/repositioned. Which is does when the container gets resized by user interaction, just not by DHTML changes.

Thanks for the replies-
Ct

createErrorMsg

2:56 pm on May 3, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Actually, what I want is to have a fancy frame around my Div, consisting of 8 images: 4 "corner" images and 4 "side" images that will get stretched to the height/width of the Div.

Ah! I wish you had said so from the start! :)

This is actually not too difficult to do. One very effective procedure involves not 8, but 5 images. These images are used as backgrounds for elements that make up the structure of the squared in element. It requires adding a few non-semantic elements to hold a few of the images, but the end result is a very nice framing effect, without tables, and with the images as backgrounds where they do not clutter up the source code.

Rather than get into the details here, I'll refer you to the article that originated the procedure. It's written by Soren Madsen and is called "Customized Borders and Corners in Flexible Layouts." It can be found on his site, here [picment.com]. Should that link get clipped, search for it using his name and "custom rounded corners" as keywords. It was also featured, long ago, as an article on ALA.

cEM

chiefthunder

3:12 pm on May 3, 2005 (gmt 0)

10+ Year Member



Catched the link :). Looks like a nice solution.

Now I can forget about nested abs divs for a while.
Thanks a lot cem.

chiefthunder

4:33 pm on May 3, 2005 (gmt 0)

10+ Year Member



I think I've found the best workaround for the abs div problem now.


<html>
<head>
[/PRE]
[PRE]

<script>
function test() {
document.getElementById("id1").innerHTML = "long<BR /> <BR /> <BR /> <BR /><BR /> <BR /> <BR /> <BR />";
//the following line refreshes the container div so the elements jump back into place (FF)
document.getElementById("parentid").innerHTML = document.getElementById("parentid").innerHTML;
}
</script>
[/PRE]
[PRE]

</head>
<body>
<a onclick="test()">click to test</a>
<DIV ID=parentid STYLE="position:absolute;top:80px;left:80px; width:100px; background:gray;">
<DIV ID=id1>short<BR /> <BR /> <BR /> <BR /> </DIV>
<DIV STYLE="position:absolute;bottom:0px;background:green">I'm a border, really!<DIV>
</DIV>
[/PRE]
[PRE]

</body>
</html>

The solution with the 5 images was very good but I would've needed a very large bg-picture since I'm making an explorer like tree - which can get very long.