Click to See Complete Forum and Search --> : Question on Positions?


swatpup32
11-03-2008, 12:05 PM
Can a div tag that is position: absolute; be positioned behind another div that is position: relative. Here is my problem. I have a container div tag that has an opacity: 0.75, however even if the child divs are set to opacity: 1.0 they still inherit the opacity of the container div. So I'm using javascript to position a fully opaque div at the same place as the child div. The problem is I don't know how to force the div created in javascript behind the child div. I'm pretty sure the answer is it can't be done, but I guess there is no harm in asking.

aj_nsc
11-03-2008, 12:47 PM
Sorry for the multiple edits, I'm having a little difficulty understanding your question. I think I've got it now.

The best way to deal with this problem (and it is a known problem with using opacity - all child elements can't have an opacity more than what they're parent element has) is to fake it.

Instead of having markup like this:


<div id="transparent">
transparent content
<div id="opaquechild">
opaque content
</div>
</div>


and use javascript to put an opaque color behind "opaquechild" is to do this:


<div id="transparent">
transparent content
</div>

<div id="opaquecontent">
opaque content
</div>


and use CSS positioning to put "opaquecontent" inside of "transparent". This will also solve of the problem of what your users with JS enabled will see.


yet another edit:

As much as an advocate I am for the method above. I couldn't resist and came up with the below code which illustrates exactly what you are trying to do (at least in FF3)


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Weird Opacity JS Thingy</title>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="description" content="" />

<style>
#parent {
opacity: 0.75;
border: 1px solid #000;
background-color: #00f;
width: 200px;
height: 200px;
position: relative;
}
#child {
border: 1px solid #000;
background-color: #f00;
width: 100px;
height: 100px;
}

#newDiv {
background-color: #f00;
width: 100px;
height: 100px;
position: absolute;
z-index: -1;
}
</style>
<script type="text/javascript">
function opacity() {
opaqueDiv = document.createElement("div");
opaqueDiv.id = "newDiv";
opaqueDiv.style.top = document.getElementById("child").offsetTop+10+"px";
opaqueDiv.style.left = document.getElementById("child").offsetLeft+10+"px";

document.body.appendChild(opaqueDiv);
}
</script>
</head>
<body onload="opacity()">

<div id="parent">
<h1>Parent</h1>
<div id="child">
<h2>Child</h2>
</div>
</div>
</body>
</html>

aj_nsc
11-03-2008, 01:17 PM
Whoops - scratch that code, the below code is better.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Weird Opacity JS Thingy/title>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="description" content="" />

<style>
#parent {
opacity: 0.75;
border: 1px solid #000;
background-color: #00f;
width: 200px;
height: 200px;
position: absolute;
top:10px;
left:10px;
z-index: 3;
}
#child {
border: 1px solid #000;
background-color: #f00;
width: 100px;
height: 100px;
}

#newDiv {
background-color: #f00;
width: 100px;
height: 100px;
position: absolute;
z-index: 2;
}

#cont {
position: relative;
z-index:1;
}
</style>
<script type="text/javascript">
function opacity() {
opaqueDiv = document.createElement("div");
opaqueDiv.id = "newDiv";
opaqueDiv.style.top = document.getElementById("child").offsetTop+12+"px";
opaqueDiv.style.left = document.getElementById("child").offsetLeft+12+"px";

document.body.appendChild(opaqueDiv);
}
</script>
</head>
<body onload="opacity()">
<div id="cont">
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
Page Content behind the div and out the other side<br />
</div>
<div id="parent">
<h1>Parent</h1>
<div id="child">
<h2>Child</h2>
</div>
</div>
</body>
</html>

swatpup32
11-03-2008, 08:20 PM
Thanks for all the work on my part. It's greatly appreciated. I guess the key is understand the z-index which is something I've never worked with before till now.

This is what I came up with before reading your post:
Basically I just duplicated the div and innerHTML. The client ends up with duplicate content which no doubt would lead to problems in the future.

<script type="text/javascript">
function itemFullOpacity() {
for (var i=0; i<document.getElementsByClassName("itemDiv").length; i++) {
var attribTop = document.getElementsByClassName("itemDiv")[i].offsetTop;
var attribLeft = document.getElementsByClassName("itemDiv")[i].offsetLeft;
var attribWidth = document.getElementsByClassName("itemDiv")[i].offsetWidth;
var attribHeight = document.getElementsByClassName("itemDiv")[i].offsetHeight;
var newDiv = document.createElement("div");
newDiv.innerHTML = document.getElementsByClassName("itemDiv")[i].innerHTML;

if (!document.getElementById("div" + i)) {
newDiv.setAttribute("class", "javaItemOpaque");
newDiv.setAttribute("id", "div" + i)
newDiv.style.top = attribTop + 15;
newDiv.style.left = attribLeft;
newDiv.style.width = attribWidth;
newDiv.style.height = attribHeight;
document.body.appendChild(newDiv);
} else {
var createdDiv = document.getElementById("div" + i);
createdDiv.style.top = attribTop + 15;
createdDiv.style.left = attribLeft;
createdDiv.style.width = attribWidth;
createdDiv.style.height = attribHeight;
}
}
}
</script>